8000 [HttpKernel] Allow using attributes for setting status code and heade… · symfony/symfony@eb43f5f · GitHub
[go: up one dir, main page]

Skip to content

Commit eb43f5f

Browse files
committed
[HttpKernel] Allow using attributes for setting status code and headers for HTTP exceptions
1 parent c79d4ab commit eb43f5f

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpKernel\Attribute;
13+
14+
use Symfony\Component\HttpFoundation\Response;
15+
16+
/**
17+
* Allows HTTP status code and headers to be set for an exception
18+
*
19+
* @author Dejan Angelov <angelovdejan@protonmail.com>
20+
*/
21+
#[\Attribute(\Attribute::TARGET_CLASS)]
22+
class HttpException
23+
{
24+
public function __construct(
25+
public readonly int $statusCode = Response::HTTP_INTERNAL_SERVER_ERROR,
26+
public readonly array $headers = []
27+
) {
28+
}
29+
}

src/Symfony/Component/HttpKernel/HttpKernel.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\HttpFoundation\Request;
1616
use Symfony\Component\HttpFoundation\RequestStack;
17< 8000 code>17
use Symfony\Component\HttpFoundation\Response;
18+
use Symfony\Component\HttpKernel\Attribute\HttpException;
1819
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
1920
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
2021
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
@@ -239,7 +240,19 @@ private function handleThrowable(\Throwable $e, Request $request, int $type): Re
239240
$response->setStatusCode($e->getStatusCode());
240241
$response->headers->add($e->getHeaders());
241242
} else {
242-
$response->setStatusCode(500);
243+
$class = new \ReflectionClass($e);
244+
$attributes = $class->getAttributes(HttpException::class);
245+
246+
if (0 === count($attributes)) {
247+
$response->setStatusCode(500);
248+
} else {
249+
$arguments = $attributes[0]->getArguments();
250+
$statusCode = $arguments["statusCode"];
251+
$headers = $arguments["headers"];
252+
253+
$response->setStatusCode($statusCode);
254+
$response->headers->add($headers);
255+
}
243256
}
244257
}
245258

src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\HttpFoundation\Request;
1919
use Symfony\Component\HttpFoundation\RequestStack;
2020
use Symfony\Component\HttpFoundation\Response;
21+
use Symfony\Component\HttpKernel\Attribute\HttpException;
2122
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
2223
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
2324
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
@@ -234,6 +235,22 @@ public function testHandleHttpException()
234235
$this->assertEquals('POST', $response->headers->get('Allow'));
235236
}
236237

238+
public function testHandleExceptionWithHttpAttribute()
239+
{
240+
$dispatcher = new EventDispatcher();
241+
$dispatcher->addListener(KernelEvents::EXCEPTION, function (ExceptionEvent $event) {
242+
$event->setResponse(new Response());
243+
});
244+
245+
$kernel = $this->getHttpKernel($dispatcher, function () {
246+
throw new NotFoundHttpExceptionWithAttribute();
247+
});
248+
$response = $kernel->handle(new Request());
249+
250+
$this->assertEquals('404', $response->getStatusCode());
251+
$this->assertEquals('example', $response->headers->get('resource'));
252+
}
253+
237254
public function getStatusCodes()
238255
{
239256
return [
@@ -525,3 +542,13 @@ function controller_func()
525542
{
526543
return new Response('foo');
527544
}
545+
546+
#[HttpException(
547+
statusCode: Response::HTTP_NOT_FOUND,
548+
headers: [
549+
'resource' => 'example'
550+
]
551+
)]
552+
class NotFoundHttpExceptionWithAttribute extends \Exception
553+
{
554+
}

0 commit comments

Comments
 (0)
0