Spiral Framework provides multiple ways to handle critical and application-level exceptions.
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
.
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.