Revision: Sat, 01 Aug 2020 19:23:52 GMT

Debug - Handling Exceptions

Spiral Framework provides multiple ways to handle critical and application-level exceptions.

Using Middleware

You can create HTTP middleware to intercept any specific exception type thrown inside your controllers. We can use Whoops to demonstrate how to write it.

$ composer require filp/whoops

And our middleware:

namespace App\Middleware;

use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class WhoopsMiddleware implements MiddlewareInterface
{
    private $responseFactory;

    public function __construct(ResponseFactoryInterface $responseFactory)
    {
        $this->responseFactory = $responseFactory;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        try {
            return $handler->handle($request);
        } catch (\Throwable $e) {
            $response = $this->responseFactory->createResponse(500);
            $response->getBody()->write($this->renderWhoops($e));

            return $response;
        }
    }

    private function renderWhoops(\Throwable $e): string
    {
        $whoops = new \Whoops\Run();
        $whoops->allowQuit(false);
        $whoops->writeToOutput(false);

        $handler = new \Whoops\Handler\PrettyPageHandler();
        $handler->handleUnconditionally(true); // whoops does not know about RoadRunner

        $whoops->prependHandler($handler);

        return $whoops->handleException($e);
    }
}

Make sure to enable this middleware via Bootloader:

use App\Middleware\WhoopsMiddleware;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Bootloader\Http\HttpBootloader;

class WhoopsBootloader extends Bootloader
{
    public function boot(HttpBootloader $http)
    {
        $http->addMiddleware(WhoopsMiddleware::class);
    }
}

Do not forget to disable default Spiral\Bootloader\Http\ErrorHandlerBootloader.

You can use this approach to suppress the specific type of exceptions in your application.

You can also handle domain-specific exceptions in Spiral\Core\CoreInterface.

Snapshots

In addition to the custom middleware framework provides a unified way to handle exceptions registration (including fatal exceptions). Such functionality is delivered by spiral/snapshots package and intended for exception registration in external monitoring solutions (for example, Sentry):

You can implement your snapshot provider via Spiral\Snapshots\SnapshotterInterface:

use Spiral\Snapshots\Snapshot;
use Spiral\Snapshots\SnapshotInterface;
use Spiral\Snapshots\SnapshotterInterface;

class MySnapshotter implements SnapshotterInterface
{
    public function register(\Throwable $e): SnapshotInterface
    {
        // register exception in log, Sentry or etc

        return new Snapshot('unique-id', $e);
    }
}

Make sure to bind your implementation to Spiral\Snapshots\SnapshotterInterface to enable it.

Edit this page