How to catch cURL errors in PHP

I am using PHP curl functions to post data to the web server from my local machine. My code is as follows:

$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_POST, true);
curl_setopt($c, CURLOPT_POSTFIELDS, $data);
$result = curl_exec($c);
if (curl_exec($c) === false) {
    echo "ok";
} else {
    echo "error";
}
curl_close($c);

Unfortunately I am not able to catch any errors like 404, 500 or network failure. So how will I get to know that data was not posted to or retrieved from the remote?


You can use the curl_error() function to detect if there was some error. For example:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $your_url);
curl_setopt($ch, CURLOPT_FAILONERROR, true); // Required for HTTP error codes to be reported via our call to curl_error($ch)
//...
curl_exec($ch);
if (curl_errno($ch)) {
    $error_msg = curl_error($ch);
}
curl_close($ch);

if (isset($error_msg)) {
    // TODO - Handle cURL error accordingly
}

See the description of libcurl error codes here

See the description of PHP curl_errno() function here

See the description of PHP curl_error() function here


If CURLOPT_FAILONERROR is false, http errors will not trigger curl errors.

<?php
if (@$_GET['curl']=="yes") {
  header('HTTP/1.1 503 Service Temporarily Unavailable');
} else {
  $ch=curl_init($url = "http://".$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF']."?curl=yes");
  curl_setopt($ch, CURLOPT_FAILONERROR, true);
  $response=curl_exec($ch);
  $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  $curl_errno= curl_errno($ch);
  if ($http_status==503)
    echo "HTTP Status == 503 <br/>";
  echo "Curl Errno returned $curl_errno <br/>";
}

you can generate curl error after its execution

$url = 'http://example.com';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if(curl_errno($ch)){
    echo 'Request Error:' . curl_error($ch);
}

and here are curl error code

if someone need more information about curl errors

<?php

    $error_codes=array(
    [1] => 'CURLE_UNSUPPORTED_PROTOCOL',
    [2] => 'CURLE_FAILED_INIT',
    [3] => 'CURLE_URL_MALFORMAT',
    [4] => 'CURLE_URL_MALFORMAT_USER',
    [5] => 'CURLE_COULDNT_RESOLVE_PROXY',
    [6] => 'CURLE_COULDNT_RESOLVE_HOST',
    [7] => 'CURLE_COULDNT_CONNECT',
    [8] => 'CURLE_FTP_WEIRD_SERVER_REPLY',
    [9] => 'CURLE_REMOTE_ACCESS_DENIED',
    [11] => 'CURLE_FTP_WEIRD_PASS_REPLY',
    [13] => 'CURLE_FTP_WEIRD_PASV_REPLY',
    [14]=>'CURLE_FTP_WEIRD_227_FORMAT',
    [15] => 'CURLE_FTP_CANT_GET_HOST',
    [17] => 'CURLE_FTP_COULDNT_SET_TYPE',
    [18] => 'CURLE_PARTIAL_FILE',
    [19] => 'CURLE_FTP_COULDNT_RETR_FILE',
    [21] => 'CURLE_QUOTE_ERROR',
    [22] => 'CURLE_HTTP_RETURNED_ERROR',
    [23] => 'CURLE_WRITE_ERROR',
    [25] => 'CURLE_UPLOAD_FAILED',
    [26] => 'CURLE_READ_ERROR',
    [27] => 'CURLE_OUT_OF_MEMORY',
    [28] => 'CURLE_OPERATION_TIMEDOUT',
    [30] => 'CURLE_FTP_PORT_FAILED',
    [31] => 'CURLE_FTP_COULDNT_USE_REST',
    [33] => 'CURLE_RANGE_ERROR',
    [34] => 'CURLE_HTTP_POST_ERROR',
    [35] => 'CURLE_SSL_CONNECT_ERROR',
    [36] => 'CURLE_BAD_DOWNLOAD_RESUME',
    [37] => 'CURLE_FILE_COULDNT_READ_FILE',
    [38] => 'CURLE_LDAP_CANNOT_BIND',
    [39] => 'CURLE_LDAP_SEARCH_FAILED',
    [41] => 'CURLE_FUNCTION_NOT_FOUND',
    [42] => 'CURLE_ABORTED_BY_CALLBACK',
    [43] => 'CURLE_BAD_FUNCTION_ARGUMENT',
    [45] => 'CURLE_INTERFACE_FAILED',
    [47] => 'CURLE_TOO_MANY_REDIRECTS',
    [48] => 'CURLE_UNKNOWN_TELNET_OPTION',
    [49] => 'CURLE_TELNET_OPTION_SYNTAX',
    [51] => 'CURLE_PEER_FAILED_VERIFICATION',
    [52] => 'CURLE_GOT_NOTHING',
    [53] => 'CURLE_SSL_ENGINE_NOTFOUND',
    [54] => 'CURLE_SSL_ENGINE_SETFAILED',
    [55] => 'CURLE_SEND_ERROR',
    [56] => 'CURLE_RECV_ERROR',
    [58] => 'CURLE_SSL_CERTPROBLEM',
    [59] => 'CURLE_SSL_CIPHER',
    [60] => 'CURLE_SSL_CACERT',
    [61] => 'CURLE_BAD_CONTENT_ENCODING',
    [62] => 'CURLE_LDAP_INVALID_URL',
    [63] => 'CURLE_FILESIZE_EXCEEDED',
    [64] => 'CURLE_USE_SSL_FAILED',
    [65] => 'CURLE_SEND_FAIL_REWIND',
    [66] => 'CURLE_SSL_ENGINE_INITFAILED',
    [67] => 'CURLE_LOGIN_DENIED',
    [68] => 'CURLE_TFTP_NOTFOUND',
    [69] => 'CURLE_TFTP_PERM',
    [70] => 'CURLE_REMOTE_DISK_FULL',
    [71] => 'CURLE_TFTP_ILLEGAL',
    [72] => 'CURLE_TFTP_UNKNOWNID',
    [73] => 'CURLE_REMOTE_FILE_EXISTS',
    [74] => 'CURLE_TFTP_NOSUCHUSER',
    [75] => 'CURLE_CONV_FAILED',
    [76] => 'CURLE_CONV_REQD',
    [77] => 'CURLE_SSL_CACERT_BADFILE',
    [78] => 'CURLE_REMOTE_FILE_NOT_FOUND',
    [79] => 'CURLE_SSH',
    [80] => 'CURLE_SSL_SHUTDOWN_FAILED',
    [81] => 'CURLE_AGAIN',
    [82] => 'CURLE_SSL_CRL_BADFILE',
    [83] => 'CURLE_SSL_ISSUER_ERROR',
    [84] => 'CURLE_FTP_PRET_FAILED',
    [84] => 'CURLE_FTP_PRET_FAILED',
    [85] => 'CURLE_RTSP_CSEQ_ERROR',
    [86] => 'CURLE_RTSP_SESSION_ERROR',
    [87] => 'CURLE_FTP_BAD_FILE_LIST',
    [88] => 'CURLE_CHUNK_FAILED');

    ?>

Since you are interested in catching network related errors and HTTP errors, the following provides a better approach:

function curl_error_test($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $responseBody = curl_exec($ch);
    /*
     * if curl_exec failed then
     * $responseBody is false
     * curl_errno() returns non-zero number
     * curl_error() returns non-empty string
     * which one to use is up too you
     */
    if ($responseBody === false) {
        return "CURL Error: " . curl_error($ch);
    }

    $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    /*
     * 4xx status codes are client errors
     * 5xx status codes are server errors
     */
    if ($responseCode >= 400) {
        return "HTTP Error: " . $responseCode;
    }

    return "No CURL or HTTP Error";
}

Tests:

curl_error_test("http://expamle.com");          // CURL Error: Could not resolve host: expamle.com
curl_error_test("http://example.com/whatever"); // HTTP Error: 404
curl_error_test("http://example.com");          // No CURL or HTTP Error