Error Handlers

Canvas uses exception-driven error handling. Controllers throw exceptions to describe failures. The framework catches them and delegates response creation to error handlers.

Core Concepts

Error handling in Canvas revolves around two core concepts:

  • Exception – Describes a failure (\Throwable)
  • Error Handler – Converts an exception into an HTTP Response

Request Failure Flow

  1. A controller throws an exception
  2. The Kernel catches it
  3. Error handlers are checked in the order they were discovered
  4. The first supporting handler returns a Response
  5. The Response is sent to the client

If no handler supports the exception, Canvas falls back to the default Kernel handler.

Framework Exceptions

Canvas throws specific exceptions for framework-level failures. For example:

Quellabs\Canvas\Exceptions\RouteNotFoundException

This exception is converted into an HTTP response (typically 404) by the error handling system.

Throwing Exceptions in Controllers

public function show(int $id) {
    $user = $this->userRepository->find($id);

    if (!$user) {
        throw new UserNotFoundException($id);
    }

    return $user;
}

Controllers focus on business logic and signal failures by throwing exceptions.

Creating an Error Handler

Error handlers implement Quellabs\Canvas\Error\ErrorHandlerInterface. Use the exception code as the HTTP status when provided. Otherwise, default to 500. Autowiring is allowed on the error handler's constructor.

Example

namespace App\Errors;

use Quellabs\Canvas\Error\ErrorHandlerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class UserNotFoundHandler implements ErrorHandlerInterface {
    public static function supports(\Throwable $e) {
        return $e instanceof UserNotFoundException;
    }

    public function handle(\Throwable $e, Request $request) {
        $status = $e->getCode() ?: 500;
        return new Response("User {$e->getUserId()} not found", $status);
    }
}

Guidelines

  • Use descriptive class names
  • Encode the HTTP status code via the exception code
  • Keep the class focused on describing the error condition

Location

Place application-specific error handlers in: src/Errors/. If desired the default location can be changed through the config/app.php configuration file.

<?php

    return [
        ...

        // Path to error handlers
        'error_handler_directory' => dirname(__FILE__) . '/../src/Errors',

        ...
    ];