CakePHP 3 Http Client timeout error handling - php

I'm trying to use the CakePHP 3 Http Client to check urls for their response status code (404, 301, 200 etc)
$http = new Client();
$response = $http->get($links[$i]['url'],[],['timeout' => '10']);
$links[$i]['http_status'] = $response->statusCode();
However, if I come across a url that timesout, the entire script fails. I'm having trouble figuring out how to add error handling so that if it does timeout, I can log it and move on.
Any ideas?

The solution was to use try/catch. I had tried this initially but missed the \ before Exception on the catch
try {
// code
} catch (\Exception $e) {
// error
}

Related

If we throw an exception that's not caught again, do we get an empty response status?

Basically, I was sending a AJAX request with an object with some missing JSON data, and I was wondering why I didn't get a status code and got no response data. The JSON is valid, but there are missing data that won't allow the code to successfully run.
So I tried it several times and the request never returned any data and there was no status code as if the server didn't respond and the request timed out. I tried with a correct JSON and it worked flawlessly (I got a 200 status and a proper server response)
public function getAssets($asset_id) {
try {
$response = $this->_services[$current_service]->get_random_asset($asset_id);
} catch (Exception $e) {
throw new Exception('Something is wrong: '.$e->getMessage(), 500);
}
}
I am not sure if this is correct, but I am guessing if I don't catch the thrown Exception by putting the function call of getAssets() in a try block or any function higher in the stack the server will not send any response and the request will timeout?

Laravel 5: Guzzle -> getStatusCode on Exception?

I am programming a little application for myself. This application is calling to different websites with the package Guzzle.
However, I want to store every request in my database with the time and the request duration time and the request status code I get. The problem I am facing here right now is that I don't know how to get the http status code when the request fails..
This is my code so far:
$client = $this->getGuzzleClient();
$request = $client->post($url, $headers, $value);
try {
$response = $request->send();
return $response->getBody();
}catch (\GuzzleHttp\Exception\RequestException $e){
dd(array($e, $e->getResponse()));
}
The $e->getResponse() returns null. I also tried to use $e->getStatusCode() or $e->getRequest()->getStatusCode(). Both are not working...
To be absolutely sure the request is valid and I deal with a real exception I call to this website https://httpstat.us/503. This returns a 503 http status code...
So, how can I get the http status code? Do you guys have any idea?
Kind regards and Thank You!
If you catch a ServerException you are catching a 5xx, if the code execution enters there Guzzle has received a 5xx. If you catch a RequestException that includes network errors too. If the code execution enters on the RequestException but does not on the ServerException means that for Guzzle is not a 5xx error but a network error.
$errorstatuscode=$exception->status;
// to get error code from Excetion Object

How to keep LineFeed in GuzzleHttp Response Body

I am doing and cUrl request using Guzzle.
$client = new GuzzleHttp\Client();
try {
$response = $client->get($url);
} catch (\GuzzleHttp\Exception\RequestException $ex) {
// handle error.
}
The server response is formatted like this:
"field1","field2","field3"\n
"value1","value2","value3"\n
"value4","","value5"\n
Using GuzzleHttp\Client, I receive the following response body
"field1","field2","field3""value1","value2","value3""value4","","value5"\n
Is it possible to set the Guzzle Client not to replace line feed chars in the response body?
We don't know what your response looks like.
We don't know how you are viewing the response.
In the presence of these two details I would have to guess that you might have to implement some type of stream decorator so that only single lines of the response are read in at a time.

Empty or too short HTTP message using HTTPRequest

I have an app that responds to a POST request with files:
https://docxgenjs.herokuapp.com/
It just echoes out (in JSON format) the files that were posted to that URL.
You can test it using a REST Console (on chrome web store).
Howewer, when I request that page using PHP, it doesn't work out:
try {
$url = 'https://docxgenjs.herokuapp.com/';
$request = new HTTPRequest($url, HTTP_METH_POST);
$request->addPostFile("config",app_path()."\\docxgen\\config.json");
$request->addPostFile("docx",app_path()."\\docxgen\\tagExample.docx");
$request->send();
$response = $request->getResponseBody();
var_dump($response);
}
catch(Exception $e)
{
var_dump($e->getMessage()); var_dump($e->getCode());
}
I get the following exception:
string(35) "Empty or too short HTTP message: ''"
int(2)
What's different between the two POST Requests, and how can I fix that ?
If I remove the two lines:
$request->addPostFile("config",app_path()."\\docxgen\\config.json");
$request->addPostFile("docx",app_path()."\\docxgen\\tagExample.docx");
They is no exception and the response of the server is the expected response {}
The issue was that the paths had to be written with / rather than \\

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.

Categories