Reading the error body in PHP curl_exec [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Using PHP curl how does one get the response body for a 400 response
When using PHP's curl_exec to call a RESTful API the documentation says http://php.net/manual/en/function.curl-exec.php
Returns TRUE on success or FALSE on failure. However, if the
CURLOPT_RETURNTRANSFER option is set, it will return the result on
success, FALSE on failure.
When curl_exec fails it returns false. However the remote server might have tried to return a helpful message to go with that error. How can we access this message using curl_exec, when it just returns false?
For example the remote API might be returning this message and a HTTP 400 status code:
{"Items":[{"Field":"FirstName","Description":"FirstName is required and cannot be null."}]}
Currently I am unable to read this error message that has been returned, instead all I get is false. I have looked at curl_info too. I do have returntransfer set on.
In C# I would use the exception.Response.GetResponseStream method and write:
private static string Post(WebClient client, string uri, string postData)
{
string response = string.Empty;
try
{
response = client.UploadString(uri, "POST", postData);
}
catch (WebException ex)
{
var stream = ex.Response.GetResponseStream(); // here
if (stream != null)
{
using (var reader = new StreamReader(stream))
{
response = reader.ReadToEnd();
}
}
}
return response;
}
How can this be done in PHP? Is curl_exec the right method or should I use something else?

You should look at curl_error
http://www.php.net/manual/en/function.curl-error.php

Related

How to catch errors when using file_get_contents on an external URL [duplicate]

This question already has answers here:
HTTP requests with file_get_contents, getting the response code
(6 answers)
Closed 8 months ago.
To make a POST request to an external url from my PHP code, I use the following snippet, posted in many topics on here:
function http_post($url, $data) {
$options = ['http' => ['header' => "Content-type: application/x-www-form-urlencoded\r\n",'method' => 'POST','content' => http_build_query($data)]];
$result = file_get_contents($url, false, stream_context_create($options));
if ($result === FALSE) { /* Handle error */}
return $result;
}
This works, but I'm struggling with the "Handle error" part. How should I implement this? More specifically:
How would I get a text version of what went wrong to store in my logs? Some of them I can of course catch by surrounding the file_get_contents in a try-catch block, but what about the cases that silently return false?
How can I know if it's an error of type 'timeout'/'connection issue' (in which case I want to try again) or of type 'website not found'/'access denied'/etc. (in which case I don't want to try again)?
file_get_contents() exists to simplify it's usage so the developer doesn't have to deal with all technical details such as if the retrieved file is on a local storage or retrieved over the netwerk. In some cases file_get_contents() is simple enough.
Perhaps this function can give you some more insight into what went wrong:
https://www.php.net/manual/en/function.error-get-last.php
if (!$result = #file_get_contents($url, false, $context)) {
$error = error_get_last();
echo "Error: " . $error['message'];
}
If you want more power over your requests and it's responses, you might need to look into other libraries such as curl (https://www.php.net/manual/en/book.curl.php)

How to get HTTP status answer from GuzzleHttp response by php Laravel?

I develop at php Laravel.
I receiving GuzzleHttp response from Mailgun as Object and can't to get from it the status.
the Object is:
O:8:"stdClass":2:{s:18:"http_response_body";O:8:"stdClass":2:{s:6:"member";O:8:"stdClass":4:{s:7:"address";s:24:"test_of_json-4#zapara.fr";s:4:"name";s:10:"not filled";s:10:"subscribed";b:1;s:4:"vars";O:8:"stdClass":0:{}}s:7:"message";s:36:"Mailing list member has been created";}s:18:"http_response_code";i:200;}
I need just last data pair:
"http_response_code";i:200;
to get it into variable, like:
$http_response_code = 200;
or even just its value.
To get string as I cited above I use
$result_ser = serialize($result);
but yet can't to extract value of variable.
Also I tried this:
$this->resultString .= \GuzzleHttp\json_decode($result_ser, true);
and get error.
Please, explain me , How to get/extract value I needed?
To take the response status code you can use the function getStatusCode :
$response = $client->request();
$statusCode = $response->getStatusCode();
while to take the body of response you can use :
$contents = $response->getBody()->getContents();
let's consider your request is something like
$response = $client->get("https://example.com");
if ( $object_res->getStatusCode() == 200 ) { // here you are checking your http status code
}
$object_res->getStatusCode() is the method to get http status code.
refer docs, there is simple example in this page.
I found that 'mailgun/mailgun' package uses its own HTTP client which also uses 'RestClient' and these classes are return stdObject.
In that Object there is property 'http_response_code' containing HTTP response code like 200, 400, 401 etc.
This property accessible by standard way $object->property and it's a solution of my query in this case.
For anybody who will read this question and answers I should to explain one thing that I not cleared in question.
I made request to the Mailgun API for subscribing member to mailing list. The API returns stdObject, not JSON or XML data.
But also there is one more strange thing - stdObject returned when request is successful only. If request fails you'll get just Exception thrown with message and without code. This forced me, if fail, to parse message body instead of get and resolve error code.
$responseObj->getStatusCode();

Get external page content regardless of response type [duplicate]

This question already has an answer here:
Need response body of HTTP 500 with file_get_contents (PHP)
(1 answer)
Closed 8 years ago.
I'm working with an API that I recently noticed is failing in the code some of the time. I retrieve it via file_get_contents, and I'm getting the error "failed to open stream: HTTP request failed!"
I plugged the URL into the browser directly and I get back a response, so I was confused. I thought to check the headers, and I noticed its coming up 403, and I have to assume that's why its failing? When its not 403, it does work. The 403 only comes up when the API authentication fails, and I have code to check if the XML that comes back says its a failure.
So really the question is, how can I get back the code, regardless of if its a 403 or not. I was going to start using simplexml_load_file since I'm loading it into SimpleXML anyway, but if there is another method I can/should use, that advice would be great too.
EDIT: I've attempted a simple curl request, but unless I've done it wrong, its also failed:
$curlObject = curl_init('https://api.eveonline.com/account/Characters.xml.aspx?userID=8166034&characterID=91242713&apiKey=B174C8B7B4364048B8A44B8C494904059D50B942BB4748FD907FF1DBF3F18282');
curl_setopt($curlObject, CURLOPT_RETURNTRANSFER, 1);
$fileContents = curl_exec($curlObject);
curl_close($curlObject);
echo $fileContents;
I would wrap the handling as specified in the duplicate question and then throw a dedicated exception when you trigger that error-response:
$legacyKey = [
'userID' => '8166034',
'apiKey' => 'B174C8B7B4364048B8A44B8C494904059D50B942BB4748FD907FF1DBF3F18282',
];
$api = new EveApi($legacyKey);
$api->define('getAccountCharacters', 'account/Characters.xml.aspx', ['characterID']);
try {
$characters = $api->getAccountCharacters($characterID = '91242713');
} catch(Exception $exception) {
printf("Exception: %s; Code: %s; Message: %s\n", get_class($exception), $exception->getCode(), $exception->getMessage());
throw $exception;
}
In this example, the default handling from the EveApi would be to throw exceptions on such errors:
<?xml version="1.0" encoding="UTF-8"?>
<eveapi version="2">
<currentTime>2013-11-02 13:06:53</currentTime>
<error code="203">Authentication failure.</error>
<cachedUntil>2013-11-03 13:06:53</cachedUntil>
</eveapi>
Can be turned into an EveApiError then as this output shows:
Exception: EveApiError; Code: 203; Message: Authentication failure.
Fatal error: Uncaught exception 'EveApiError' with message
'Authentication failure.' in ...
That would not only wrap the error handling but also the API access allowing you to inject your own API for testing purposes.
Additionally you can wrap the different but common return types.

RESTful API Error Handling

I have a simple function that makes a cURL request to my RESTful API, and it returns data as it should when a successful request is made. My problem is, when a user perhaps gives the API wrong data or the API can't do what is requested, I don't know how to return error responses (e.g. 404s, 500s).
How would I go about doing this?
At the moment I have the following. In my API client
class Awesome_Api {
static function request($url, $data, $method)
{
// cURL stuffs here...
if (successful)
{
return (success response)
}
else
{
return (error response)
}
}
}
and
$response = Awesome_Api::request($url, $data, $method);
Now how do I return an error response code from the API, and handle it in the client end?
Use the header function to return error codes, like this:
header('HTTP/1.1 500 Internal Server Error');
or
header('HTTP/1.1 404 Not found');
It is very important that you make sure nothing has been written to the output before calling this function, otherwise it will not work as you expect.
In your client API, you can use the curl_error() and curl_errno() functions to retrieve information about the error number and message returned from the server.

how to custom error msg with PHP if can't connect to web service (JSON)

i'm connecting to a webservice using PHP and JSON. the connection is good but i want to add 2 error messages when (1) connection to the webservice is lost and (2) if webservice returns a http 500 error.
any ideas on how to do that?? i'm new to json so not sure how to do that...
this is how i connect and get data form the webservice
$url = "http://webservice.com/{$account}?loc={$loc}";
$content = file_get_contents($url);
$json = json_decode($content, true);
For error 1:
file_get_contents will return FALSE if what it is trying to load fails.
For error 2:
Depending on what your HTTP Error 500 outputs on the page, you can simply use file_get_contents and look for a certain string indicating the error using strpos and act accordingly.
Reference: http://php.net/manual/en/function.strpos.php

Categories