When using Guzzle, an HTTP client for PHP, to make HTTP requests, you may encounter various HTTP errors. These can range from client-side errors (4xx status codes) to server-side errors (5xx status codes). Handling these errors correctly is important for robust application development.
Guzzle throws exceptions for errors that occur during a transfer. Here's how you can handle them:
- Catch Exceptions: Guzzle throws different exceptions based on the type of error:
GuzzleHttp\Exception\ClientException
: Thrown for 4xx errors.GuzzleHttp\Exception\ServerException
: Thrown for 5xx errors.GuzzleHttp\Exception\ConnectException
: Thrown in case of a networking error, like when a request fails to connect.GuzzleHttp\Exception\RequestException
: The base class for the above exceptions, thrown when a request fails for any reason.
You can catch these exceptions using a try-catch block. Here's an example:
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\Exception\RequestException;
$client = new Client();
try {
$response = $client->request('GET', 'https://example.com/api/resource');
echo $response->getBody();
} catch (ClientException $e) {
// Handle client exceptions (4xx errors)
echo "Client error: " . $e->getMessage();
} catch (ServerException $e) {
// Handle server exceptions (5xx errors)
echo "Server error: " . $e->getMessage();
} catch (RequestException $e) {
// Handle any other request-related errors
echo "Request error: " . $e->getMessage();
}
- Middleware: Guzzle allows you to attach middleware to the handler stack that can intercept the request and response process. You can use middleware to handle errors in a more generic way.
Here's an example of how you could log all exceptions without stopping the script:
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
$stack = \GuzzleHttp\HandlerStack::create();
$stack->push(Middleware::mapRequest(function (RequestInterface $request) {
// Modify the request if needed
return $request;
}));
$stack->push(Middleware::mapResponse(function (ResponseInterface $response) {
// Handle the response
return $response;
}));
$stack->push(Middleware::retry(function ($retry, $request, $response, $exception) {
// Logic for retrying a request if needed
return false;
}));
$stack->push(Middleware::httpErrors(function ($request, $response, $exception) {
// Don't throw exceptions on HTTP protocol errors. Handle them here instead.
if ($exception instanceof RequestException) {
// Log the error or take some other action
}
return $response;
}));
$client = new Client(['handler' => $stack]);
$response = $client->request('GET', 'https://example.com/api/resource');
- HTTP Status Code Checking: Sometimes you might want to handle HTTP errors manually by checking the status code of the response. You can disable Guzzle's exception throwing for HTTP errors by setting the
http_errors
request option tofalse
.
use GuzzleHttp\Client;
$client = new Client();
$response = $client->request('GET', 'https://example.com/api/resource', [
'http_errors' => false, // Disable throwing exceptions on an HTTP protocol error
]);
if ($response->getStatusCode() >= 400) {
// Handle error based on status code
echo "Error: " . $response->getStatusCode();
} else {
echo $response->getBody();
}
By properly handling HTTP errors using the approaches mentioned above, you can ensure that your application can gracefully handle unexpected issues with the external services it interacts with.