Testing Your Package README Code Snippets
Package maintainers use a README to show readers how to install a package, configure it, and complete a task. If the package…
When PHP code sends an HTTP request with Laravel’s HTTP client, failure takes one of two forms: the server returns an error status, or a connection problem prevents the client from getting a response. Laravel handles these cases differently. By default, a 4xx or 5xx response is returned for your code to inspect; a connection failure can throw an exception.
Handle each failure based on what happened. Check the response when a status such as 404 is an expected outcome. Call throw() when an error status should stop the normal code path. Catch connection exceptions separately when the request fails before the server sends a response.
An HTTP response has a status code, such as 404. For 4xx and 5xx status codes, Laravel’s HTTP client returns a response object instead of automatically throwing an exception. A timeout or DNS failure means the request did not produce a response to inspect. Laravel can throw a ConnectionException for these connection failures. The Laravel HTTP client documentation describes these as separate failure paths.
You can check a returned response with methods such as successful(), failed(), clientError(), and serverError(). Laravel classifies 2xx responses as successful, and failed() checks for 4xx or 5xx responses. It does not classify a 3xx redirect as a failure, so handle redirects separately if they matter to your request.
$response = Http::get($url);
if ($response->notFound()) {
return null;
}
if ($response->failed()) {
// Handle other 4xx or 5xx responses.
}
return $response->json();
Checking the response lets your code handle expected statuses as normal branches. For example, a lookup can treat 404 as “no record” and handle other 4xx or 5xx responses differently.
throw() when an error status should interrupt the request flowCall throw() on a response when a 4xx or 5xx status should stop the code’s normal path. Laravel then throws an Illuminate\Http\Client\RequestException, an exception that carries the error response. If the status is not an error, throw() returns the response and the code can keep using it.
$response = Http::post($url, $payload)->throw();
return $response->json();
Check the response when its status determines what the code should do. A 404 might mean a record is absent, while a 422 response might contain validation details for the caller to handle. When a status should stop normal processing, throw() raises an exception that a surrounding catch block can handle.
Laravel also provides conditional throw methods, including throwIfStatus(403) and throwIfClientError(). The HTTP client documentation lists these alongside the response-check methods.
Catch RequestException when throw() turns an error response into an exception. Its response property gives you access to the status code and response body. Catch ConnectionException for failures such as timeouts, where there may be no response to inspect.
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\RequestException;
try {
$response = Http::post($url, $payload)->throw();
return $response->json();
} catch (RequestException $e) {
$status = $e->response->status();
// Inspect the response or translate the error for the caller.
} catch (ConnectionException $e) {
// Handle a request that failed before returning a response.
}
Choose how to handle the error based on what the caller can do next. For a RequestException, inspect the server’s response and decide whether to report a validation error, handle a conflict, or log an upstream failure. For a ConnectionException, handle the fact that the request received no response. A broad catch can make sense at a boundary that handles all unexpected errors, but it should not hide the difference when these failures need different responses.
Use response checks when a status is an expected branch in the integration. Use throw() when an error response makes the rest of the operation invalid and an exception-handling boundary will deal with it. In either case, account for connection failures separately if the request must handle them.
Laravel also supports retries, but you should not automatically retry every failure. For example, a request that changes data needs a retry policy suited to that action. Laravel’s retry documentation shows how a callback can decide whether to retry based on the exception. It also notes that setting throw: false returns the last failed response after retries, while connection failures still throw a ConnectionException.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com