Contributed by Angelov Dejan
in #48352
and #48747.
PHP attributes allow to define machine-readable metadata in your code instead
of having to add that configuration in a separate file. With each new Symfony
version we add more attributes that you can optionally use. In Symfony 6.3 we've
added new attributes to configure HTTP exceptions.
Currently, to create your own HTTP exceptions, you need to implement HttpExceptionInterface
(or extend the HttpException
base class) and configure it in the
framework.exceptions option:
use App\Domain\Exception\Order\OrderNotFound;
use Symfony\Component\HttpKernel\Exception\HttpException;
class OrderNotFound extends HttpException
{
public static function create(string $id): self
{
return new self(
statusCode: Response::HTTP_NOT_FOUND,
message: sprintf('The order "%s" could not be found.', $id),
headers: ['x-header' => 'foo'],
);
}
}
# config/packages/exceptions.yaml
framework:
exceptions:
App\Domain\Exception\Order\OrderNotFound:
log_level: 'debug'
status_code: 404
In Symfony 6.3, the above code and configuration still work, but you can
optionally replace them by the following PHP attributes:
use App\Domain\Exception\Order\OrderNotFound;
use Psr\Log\LogLevel;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\WithHttpStatus;
use Symfony\Component\HttpKernel\Attribute\WithLogLevel;
#[WithHttpStatus(Response::HTTP_NOT_FOUND, headers: ['x-header' => 'foo'])]
#[WithLogLevel(LogLevel::DEBUG)]
class OrderNotFound extends \Exception
{
// ...
public function getMessage(): string
{
return sprintf('The order "%s" could not be found.', $this->order->getId());
}
}
That's all. You no longer need to configure anything in the framework.exceptions
option. In addition to having all the information in a single file, this also removes
the coupling of your HTTP exceptions with the HttpKernel component. In other words,
your domain exceptions are decoupled from the infrastructure code.
If your application uses both attributes and the framework.exceptions
option,
the configuration will have more priority than the attributes.
Sponsor the Symfony project.