Using PHP curl how does one get the response body for a 400 response
Asked Answered
C

4

20

The api I'm calling returns a json object of validation errors with the HTTP code 400. I implemented the client using PHP's curl library, but on error curl_exec returns false. How can I get the response body on error?

Note that I am setting curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

Conceal answered 15/6, 2011 at 20:27 Comment(1)
Please specifiy in your question what "validation errors with the HTTP code 400" are.Inversely
G
23

You can unset CURLOPT_FAILONERROR for once. And adding your error status code to CURLOPT_HTTP200ALIASES as expected might also help.

 curl_setopt($conn, CURLOPT_FAILONERROR, false);
 curl_setopt($conn, CURLOPT_HTTP200ALIASES, (array)400);

(libcurl also has a CURLOPT_ERRORBUFFER, but you cannot use that option from PHP.)

Btw, curl behaves correctly by not returning the response body in case of 4xx errors. Not sure if that can be overriden. So you might have to migrate to PEAR HTTP_Request2 or a similar HTTP request class where you can deviate from the standard.

Grunenwald answered 15/6, 2011 at 20:37 Comment(4)
The 200 alias thing should work. I can then check the response code instead of relying on curl_exec returning false. Thanks!Conceal
"curl behaves correctly by not returning the response body in case of 4xx errors" Can you say more about that? The RFC seems to suggest otherwise: the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included entity to the user.Minnich
@Frank: The RFC recommendation pertains to servers. From an API point of view it is however undesired to return informational and unstructured results in case of errors. They are only for human consumption, it's recommended for browsers, but very uncommon for automated user agents (fopen wrappers behave similarly). My point was just that this is expected/default behaviour of curl, not e.g. a bug.Grunenwald
Then let me rephrase the problem as I see it: How would one go about logging the informational error response body for consumption by the human who is troubleshooting the application that is encountering HTTP errors when connecting to a web service?Selfgoverned
N
9

I was able to get content from a 400 response by setting FAILONERROR to false, WITHOUT having to also alias 400 as a normal 200 response.

Nonanonage answered 18/2, 2015 at 19:8 Comment(0)
L
5

Add this:

curl_setopt($ch, CURLOPT_HTTP200ALIASES, array(400));
Laundes answered 15/6, 2011 at 20:38 Comment(1)
Shoul be curl_setopt($ch, CURLOPT_HTTP200ALIASES, array(400));. Operator => is unexpected here.Catlin
B
0

Here's how I used curl and got the full response body on a 403 error. You trick it setting CURLOPT_FAILONERROR to false, so it doesn't fail on error (and hides the response body), and then check the response HTTP code:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "http://example.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 0); // Do not fail on HTTP errors
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // follow redirects
curl_setopt($ch, CURLOPT_HEADER, 0); // Do not include header in output

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if($response === false) {
    echo 'Curl error: ' . curl_error($ch);
}

if($httpCode >= 400) {
    // The request did not succeed, but we got a HTTP response
    echo 'HTTP error: ' . $httpCode . ' with message: ' . $response;
} elseif($response !== false) {
    // Success
    echo 'Successful request: ' . $response;
}

curl_close($ch);
Blub answered 28/7, 2023 at 1:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.