The Spiral Framework provides the Exceptions
component for handling exceptions in an application.
It also provides an interface and implementation of ExceptionHandlerInterface
, functionality of Reporters
and Renderers
.
The component is available and configured by default in the application bundle.
To enable the component, you need to add ExceptionHandler
class as exceptionHandler
parameter when you create
an application instance.
// app.php
$app = App::create(
directories: ['root' => __DIR__],
exceptionHandler: \Spiral\Exceptions\ExceptionHandler::class
)->run();
Note
The application bundle uses theApp\Exception\Handler
class, which is inherited fromExceptionHandler
.
The application bundle contains App\Bootloader\ExceptionHandlerBootloader
that registers some reporters
and renderers. You can add your own renderers and reporters in this bootloader.
namespace App\Bootloader;
use App\ErrorHandler\ViewRenderer;
use App\Exception\CollisionRenderer;
use Spiral\Boot\AbstractKernel;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Exceptions\ExceptionHandler;
use Spiral\Exceptions\ExceptionHandlerInterface;
use Spiral\Exceptions\Renderer\JsonRenderer;
use Spiral\Exceptions\Reporter\FileReporter;
use Spiral\Exceptions\Reporter\LoggerReporter;
use Spiral\Http\ErrorHandler\RendererInterface;
use Spiral\Http\Middleware\ErrorHandlerMiddleware\EnvSuppressErrors;
use Spiral\Http\Middleware\ErrorHandlerMiddleware\SuppressErrorsInterface;
use Spiral\Ignition\IgnitionRenderer;
final class ExceptionHandlerBootloader extends Bootloader
{
protected const BINDINGS = [
SuppressErrorsInterface::class => EnvSuppressErrors::class,
RendererInterface::class => ViewRenderer::class,
];
public function init(AbstractKernel $kernel): void
{
$kernel->running(static function (ExceptionHandler $handler): void {
$handler->addRenderer(new CollisionRenderer());
$handler->addRenderer(new JsonRenderer());
});
}
public function boot(
ExceptionHandlerInterface $handler,
LoggerReporter $logger,
FileReporter $files,
IgnitionRenderer $ignition
): void {
$handler->addReporter($logger);
$handler->addReporter($files);
$handler->addRenderer($ignition);
}
}
The Exceptions
component allows creating and registering exception reporters
.
The interface Spiral\Exceptions\ExceptionReporterInterface
for reporters is very simple, it contains one report
method, which accepts an exception.
namespace Spiral\Exceptions;
interface ExceptionReporterInterface
{
public function report(\Throwable $exception): void;
}
The Spiral\Exceptions\Reporter\LoggerReporter
reporter are available out of the box.
Additionally, the Spiral Framework provides a Spiral\Exceptions\Reporter\FileReporter
reporter that isn't part
of the Exceptions
component but is available by default in the application.
This reporter adds an ability to log an exception using a logger registered in the application. A logger reporter is enabled by default in the application bundle.
This reporter adds the ability to create and save in a file snapshot
with detailed information from an exception.
In the application bundle this reporter enabled by default.
To add a new reporter, use the addReporter
method in the ExceptionHandler
class. By default, this class is bound
to the ExceptionHandlerInterface
interface and we can get it from the container using it. You can use the
Spiral\Boot\Environment\AppEnvironment
class to determine the current application environment and
register reporters based on that.
namespace App\Bootloader;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Boot\Environment\AppEnvironment;
use Spiral\Exceptions\ExceptionHandlerInterface;
use Spiral\Exceptions\Reporter\LoggerReporter;
use Spiral\Exceptions\Reporter\FileReporter;
use Spiral\Ignition\IgnitionRenderer;
use Spiral\Sentry\SentryReporter;
final class ExceptionHandlerBootloader extends Bootloader
{
public function boot(
ExceptionHandlerInterface $handler,
LoggerReporter $logger,
FileReporter $files,
IgnitionRenderer $ignition,
SentryReporter $sentry,
AppEnvironment $env
): void {
$handler->addReporter($logger);
if ($env->isLocal()) {
$handler->addRenderer($ignition);
$handler->addReporter($files);
} else {
$handler->addReporter($sentry);
}
}
}
The Exceptions
component allows to create and register the exception renderers
.
Renders are used to create a string representation
of the exception according to the required format
.
The application can contain different renders for different formats.
Renderers must implement the Spiral\Exceptions\ExceptionRendererInterface
interface with two methods canRender
and
render
.
namespace Spiral\Exceptions;
interface ExceptionRendererInterface
{
/**
* @param string|null $format Preferred format
*/
public function render(
\Throwable $exception,
?Verbosity $verbosity = Verbosity::BASIC,
string $format = null,
): string;
public function canRender(string $format): bool;
}
The Spiral\Exceptions\Renderer\ConsoleRenderer
, Spiral\Exceptions\Renderer\JsonRenderer
,
Spiral\Exceptions\Renderer\PlainRenderer
renderers are available out of the box.
Renderer | Formats |
---|---|
ConsoleRenderer | console, cli |
JsonRenderer | application/json, json |
PlainRenderer | text/plain, text, plain, cli, console |
To add a new renderer, use the addRenderer
method in the ExceptionHandler
class. By default, this class is bound
to the ExceptionHandlerInterface
interface and we can get it from the container using it.
namespace App\Bootloader;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Exceptions\ExceptionHandlerInterface;
final class ExceptionHandlerBootloader extends Bootloader
{
public function boot(ExceptionHandlerInterface $handler): void
{
$handler->addRenderer(new SomeRenderer());
}
}