Saloon has a powerful exception handler with many descriptive exceptions you can use in your application.
When you send a request, Saloon won't do anything if the request fails, but by default, it will use the status code to determine if a request is successful or not. The only exception to this is if Saloon cannot connect to an API, which will throw a FatalRequestException
.
<?php
$forge = new ForgeConnector;
$response = $forge->send(new ErrorRequest);
$response->failed(); // true
$response->status(); // 500
$response->body(); // {"message": "Server Error"}
You may wish to throw an exception whenever a request fails (4xx or 5xx response). You can add the AlwaysThrowOnErrors
trait on your connector, and then every request that fails will throw an exception.
<?php
use Saloon\Traits\Plugins\AlwaysThrowOnErrors;
class ForgeConnector extends Connector
{
use AlwaysThrowOnErrors;
// {...}
}
On a per-response basis, you may use the throw
method after sending your response. This method will throw an exception if the response has a "failed" HTTP status code like 4xx or 5xx.
<?php
$forge = new ForgeConnector;
$response = $forge->send(new ErrorRequest);
// throws InternalServerErrorException (extends ServerException)
$response->throw();
Saloon's default exception handler contains the following exceptions based on the status code and severity of the exception. These are thrown depending on the method you use below.
SaloonException
├── FatalRequestException (Connection Errors)
└── RequestException (Request Errors)
├── ServerException (5xx)
│ ├── InternalServerErrorException (500)
│ ├── ServiceUnavailableException (503)
│ └── GatewayTimeoutException (504)
└── ClientException (4xx)
├── UnauthorizedException (401)
├── PaymentRequiredException (402)
├── ForbiddenException (403)
├── NotFoundException (404)
├── MethodNotAllowedException (405)
├── RequestTimeOutException (408)
├── UnprocessableEntityException (422)
└── TooManyRequestsException (429)
When sending requests using sendAsync
or using request pooling, you will receive a PromiseInterface
instance. Since this class catches exceptions, Saloon will automatically pass the request exception in the otherwise
block, and you do not have to use the throw
method.
<?php
use Saloon\Http\Response;
$forge = new ForgeConnector('api-token');
$promise = $forge->sendAsync(new GetServersRequest);
$promise
->then(function (Response $response) {
// Handle successful response
})
->otherwise(function (RequestException $exception) {
// Handle failed request
});
You may integrate with an API which returns a 200 response status but with an error message in the response body. To handle this, you can extend the hasRequestFailed
method on your connector or request.
{% tabs %} {% tab title="Connector" %}
<?php
use Saloon\Http\Connector;
use Saloon\Http\Response;
class ForgeConnector extends Connector
{
// {...}
public function hasRequestFailed(Response $response): ?bool
{
return str_contains($response->body(), 'Server Error');
}
}
{% endtab %}
{% tab title="Request" %}
<?php
use Saloon\Http\Request;
use Saloon\Http\Response;
class ErrorRequest extends Request
{
// {...}
public function hasRequestFailed(Response $response): ?bool
{
return str_contains($response->body(), 'Server Error');
}
}
{% endtab %} {% endtabs %}
By default, Saloon will use the exceptions listed above, but you may choose to return your own exception if a request has failed. Just extend the getRequestException
method on either your connector or request. You will receive an instance of the response and a sender exception, which may be nullable.
{% tabs %} {% tab title="Connector" %}
<?php
use Saloon\Http\Connector;
use Saloon\Http\Response;
use \Throwable;
class ForgeConnector extends Connector
{
// {...}
public function getRequestException(Response $response, ?Throwable $senderException): ?Throwable
{
return new CustomException('Oh yee-naw!', $response, $senderException);
}
}
{% endtab %}
{% tab title="Request" %}
<?php
use Saloon\Http\Request;
use Saloon\Http\Response;
use \Throwable;
class ErrorRequest extends Request
{
// {...}
public function getRequestException(Response $response, ?Throwable $senderException): ?Throwable
{
return new CustomException('Oh yee-naw!', $response, $senderException);
}
}
{% endtab %} {% endtabs %}
{% hint style="info" %}
Priority is given to the request when you extend the getRequestException
method on both your connector and request.
{% endhint %}