Skip to main content

Error Handler

RestServer provides a built-in error handling system that intercepts exceptions and returns formatted error messages according to the OutputProcessor defined in the route.

How it works

  1. Each route has an OutputProcessor that will handle the output of the route. (See OutputProcessor)
  2. Initialize the HttpRequestHandler (it will handle the request and call the route)
  3. Once an exception is thrown, the OutputProcessor will call the ErrorHandler to handle the exception and return a detailed message (debug, dev, etc) or a simple one suitable for production.

Configuration

Setting a Logger

You can provide a PSR-3 compatible logger to the HttpRequestHandler when initializing it:

<?php
use ByJG\RestServer\HttpRequestHandler;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

// Create a logger
$logger = new Logger('app');
$logger->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));

// Initialize with logger
$server = new HttpRequestHandler($logger);
$server->handle($routeList);

If no logger is provided, a NullLogger instance will be used (no logging).

Disabling the Error Handler

You can disable the error handler completely and handle the exceptions by yourself.

<?php
use ByJG\RestServer\HttpRequestHandler;

$server = new HttpRequestHandler();
$server->withErrorHandlerDisabled(); // Disable the error handler completely
try {
$server->handle($routeList);
} catch (\Exception $ex) {
// Handle the exception
}

Enabling the Detailed Error Handler

You can enable the detailed error handler. It will return a detailed message with the exception message, stack trace, etc.

<?php
use ByJG\RestServer\HttpRequestHandler;

$server = new HttpRequestHandler();
$server->withDetailedErrorHandler(); // Enable the detailed error handler, for debug purposes
$server->handle($routeList);

Enabling The Twirp Error Handler

If you are implementing a callback or API that connects to a service handler then you might need to return the errors as the twirp service expects.

To do that change the OutputProcessor to JsonTwirpOutputProcessor.

See how to change the OutputProcessor here.

Exception Types

HttpResponseException Base Class

All HTTP exception classes in RestServer extend from HttpResponseException, which provides common functionality for handling HTTP error responses.

Base Class Methods:

MethodDescription
getStatusCode(): intReturns the HTTP status code (e.g., 404, 500)
getStatusMessage(): stringReturns the status message (e.g., "Not Found", "Internal Server Error")
getMeta(): arrayReturns additional metadata associated with the exception
setResponse(HttpResponse $response): voidAssociates an HttpResponse object with the exception
sendHeader(): voidSends the appropriate HTTP status code header

Constructor:

public function __construct(
int $statusCode,
string $message = "",
int $code = 0,
?\Throwable $previous = null,
array $meta = []
)

Example using base class methods:

<?php
use ByJG\RestServer\Exception\Error404Exception;

try {
throw new Error404Exception("User not found", 0, null, ['user_id' => 123]);
} catch (HttpResponseException $e) {
$statusCode = $e->getStatusCode(); // 404
$statusMsg = $e->getStatusMessage(); // "Not Found"
$meta = $e->getMeta(); // ['user_id' => 123]
$message = $e->getMessage(); // "User not found"
}

Built-in Exception Classes

RestServer provides several exception types that map to different HTTP status codes:

Exception ClassHTTP Status CodeDescription
Error400Exception400Bad Request
Error401Exception401Unauthorized
Error402Exception402Payment Required
Error403Exception403Forbidden
Error404Exception404Not Found
Error405Exception405Method Not Allowed
Error406Exception406Not Acceptable
Error408Exception408Request Timeout
Error409Exception409Conflict
Error412Exception412Precondition Failed
Error415Exception415Unsupported Media Type
Error422Exception422Unprocessable Entity
Error429Exception429Too Many Requests
Error500Exception500Internal Server Error
Error501Exception501Not Implemented
Error503Exception503Service Unavailable
Error520Exception520Unknown Error

Using Custom Status Codes

You can use the ErrorCustomStatusException to define your own HTTP status codes:

<?php
use ByJG\RestServer\Exception\ErrorCustomStatusException;

// Throws an exception with custom status code 499 and message
throw new ErrorCustomStatusException(499, "Custom Status Message", "Detailed error explanation");

Using Metadata with Exceptions

All HTTP exceptions in RestServer support metadata, which allows you to include additional structured information with your error responses:

<?php
use ByJG\RestServer\Exception\Error400Exception;

// Basic exception
throw new Error400Exception("Validation failed");

// Exception with metadata
throw new Error400Exception("Validation failed", 0, null, [
'fields' => [
'email' => 'Invalid email format',
'password' => 'Password must be at least 8 characters'
],
'request_id' => '12345-abcde',
'documentation_url' => 'https://example.com/api/errors#validation'
]);

The metadata will be included in the response according to the OutputProcessor format.

Custom Error Handling with Metadata

You can create custom error handlers that process exception metadata in specific ways:

<?php
// Example of a controller with custom error handling
public function processRequest(HttpRequest $request, HttpResponse $response)
{
try {
// Business logic...
$this->validateData($request->body());
} catch (Error400Exception $ex) {
$metadata = $ex->getMeta();

// Log specific metadata fields
$this->logger->error("Validation error", [
'fields' => $metadata['fields'] ?? [],
'request_id' => $metadata['request_id'] ?? null
]);

// Rethrow the exception for the framework to handle
throw $ex;
}
}