Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 71f66e3

Browse files
committed
Fix error pages
1 parent d89d3fc commit 71f66e3

53 files changed

Lines changed: 362 additions & 23 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

assets/css/easyadmin-theme/errors.css

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,23 @@
33
body.error .error-message {
44
max-inline-size: 500px;
55
min-block-size: 400px;
6-
padding: 45px;
6+
padding: 45px 15px;
7+
}
8+
@media (min-width: 992px) {
9+
body.error .error-message {
10+
padding: 45px;
11+
}
712
}
813
body.error .error-message h1 {
914
color: var(--color-danger);
15+
display: flex;
16+
align-items: center;
1017
font-size: var(--font-size-lg);
1118
font-weight: 600;
19+
margin-block-end: 1em;
1220
}
13-
body.error .error-message h1 i {
14-
margin-inline-end: 4px;
21+
body.error .error-message h1 .icon {
22+
margin-inline-end: 6px;
23+
line-height: 1;
24+
font-size: 110%;
1525
}

config/services.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
->arg(0, '%kernel.debug%')
135135
->arg(1, service(AdminContextProvider::class))
136136
->arg(2, service('twig'))
137+
->arg(3, service('logger')->nullOnInvalid())
137138
->tag('kernel.event_listener', ['event' => 'kernel.exception', 'priority' => -64])
138139

139140
->set(EasyAdminTwigExtension::class)
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/entrypoints.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"entrypoints": {
33
"app": {
44
"css": [
5-
"/app.cf59bc42.css"
5+
"/app.f338b557.css"
66
],
77
"js": [
88
"/app.8c79e3ec.js"

public/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"app.css": "app.cf59bc42.css",
2+
"app.css": "app.f338b557.css",
33
"app.js": "app.8c79e3ec.js",
44
"form.js": "form.5bccac01.js",
55
"page-layout.js": "page-layout.6e9fe55d.js",

src/EventListener/AdminRouterSubscriber.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface;
88
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\DashboardControllerInterface;
99
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Router\AdminRouteGeneratorInterface;
10+
use EasyCorp\Bundle\EasyAdminBundle\Exception\BaseException;
1011
use EasyCorp\Bundle\EasyAdminBundle\Factory\AdminContextFactory;
1112
use EasyCorp\Bundle\EasyAdminBundle\Factory\ControllerFactory;
1213
use EasyCorp\Bundle\EasyAdminBundle\Registry\AdminControllerRegistry;
@@ -129,7 +130,26 @@ public function onKernelRequestPrettyUrls(RequestEvent $event): void
129130
$actionName = $request->attributes->get(EA::CRUD_ACTION);
130131

131132
$crudControllerInstance = $this->controllerFactory->getCrudControllerInstance($crudControllerFqcn, $actionName, $request);
132-
$adminContext = $this->adminContextFactory->create($request, $dashboardControllerInstance, $crudControllerInstance, $actionName);
133+
134+
try {
135+
$adminContext = $this->adminContextFactory->create($request, $dashboardControllerInstance, $crudControllerInstance, $actionName);
136+
} catch (BaseException $e) {
137+
// if context creation fails (e.g. entity not found), create a context
138+
// without the entity so the ExceptionListener can still render the
139+
// EasyAdmin error page with the proper layout
140+
$entityId = $request->attributes->get(EA::ENTITY_ID) ?? $request->query->get(EA::ENTITY_ID);
141+
$request->attributes->remove(EA::ENTITY_ID);
142+
$request->query->remove(EA::ENTITY_ID);
143+
144+
$adminContext = $this->adminContextFactory->create($request, $dashboardControllerInstance, $crudControllerInstance, $actionName);
145+
$request->attributes->set(EA::CONTEXT_REQUEST_ATTRIBUTE, $adminContext);
146+
$this->requestAlreadyProcessedAsPrettyUrl = true;
147+
148+
// restore the entity ID so the exception message is accurate
149+
$request->attributes->set(EA::ENTITY_ID, $entityId);
150+
151+
throw $e;
152+
}
133153
}
134154

135155
$request->attributes->set(EA::CONTEXT_REQUEST_ATTRIBUTE, $adminContext);

src/EventListener/ExceptionListener.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Provider\AdminContextProviderInterface;
66
use EasyCorp\Bundle\EasyAdminBundle\Exception\BaseException;
77
use EasyCorp\Bundle\EasyAdminBundle\Exception\FlattenException;
8+
use Psr\Log\LoggerInterface;
89
use Symfony\Component\HttpFoundation\Response;
910
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
1011
use Twig\Environment;
@@ -25,6 +26,7 @@ public function __construct(
2526
private readonly bool $kernelDebug,
2627
private readonly AdminContextProviderInterface $adminContextProvider,
2728
private readonly Environment $twig,
29+
private readonly ?LoggerInterface $logger = null,
2830
) {
2931
}
3032

@@ -38,27 +40,37 @@ public function onKernelException(ExceptionEvent $event): void
3840
return;
3941
}
4042

41-
if ($this->kernelDebug || !$exception instanceof BaseException) {
43+
if ($this->kernelDebug) {
4244
return;
4345
}
4446

45-
if (null === $this->adminContextProvider->getContext()) {
47+
if (!$exception instanceof BaseException && null === $this->adminContextProvider->getContext()) {
4648
return;
4749
}
4850

49-
// TODO: check why these custom error pages don't work
50-
$event->setResponse($this->createExceptionResponse(FlattenException::create($exception)));
51+
try {
52+
$event->setResponse($this->createExceptionResponse(FlattenException::createFromThrowable($exception)));
53+
} catch (\Throwable $renderingError) {
54+
$this->logger?->warning('EasyAdmin error page rendering failed, falling back to default error handling.', [
55+
'rendering_error' => $renderingError->getMessage(),
56+
'original_exception' => $exception::class,
57+
]);
58+
}
5159
}
5260

5361
public function createExceptionResponse(FlattenException $exception): Response
5462
{
5563
$context = $this->adminContextProvider->getContext();
56-
$exceptionTemplatePath = null === $context ? '@EasyAdmin/exception.html.twig' : $context->getTemplatePath('exception');
57-
$layoutTemplatePath = null === $context ? '@EasyAdmin/layout.html.twig' : $context->getTemplatePath('layout');
5864

59-
return new Response($this->twig->render($exceptionTemplatePath, [
65+
if (null === $context) {
66+
return new Response($this->twig->render('@EasyAdmin/exception_standalone.html.twig', [
67+
'exception' => $exception,
68+
]), $exception->getStatusCode());
69+
}
70+
71+
return new Response($this->twig->render($context->getTemplatePath('exception'), [
6072
'exception' => $exception,
61-
'layout_template_path' => $layoutTemplatePath,
73+
'layout_template_path' => $context->getTemplatePath('layout'),
6274
]), $exception->getStatusCode());
6375
}
6476

src/Exception/FlattenException.php

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use EasyCorp\Bundle\EasyAdminBundle\Context\ExceptionContext;
66
use Symfony\Component\ErrorHandler\Exception\FlattenException as BaseFlattenException;
7+
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
78

89
/**
910
* @author Maxime Steinhausser <[email protected]>
@@ -17,12 +18,38 @@ final class FlattenException extends BaseFlattenException
1718
*/
1819
public static function create(\Exception $exception, ?int $statusCode = null, array $headers = []): static
1920
{
20-
if (!$exception instanceof BaseException) {
21-
throw new \RuntimeException(sprintf('You should only try to create an instance of "%s" with a "EasyCorp\Bundle\EasyAdminBundle\Exception\BaseException" instance, or subclass. "%s" given.', __CLASS__, $exception::class));
21+
return static::createFromThrowable($exception, $statusCode, $headers);
22+
}
23+
24+
/**
25+
* @param array<mixed> $headers
26+
*/
27+
public static function createFromThrowable(\Throwable $exception, ?int $statusCode = null, array $headers = []): static
28+
{
29+
if ($exception instanceof BaseException) {
30+
$e = parent::createFromThrowable($exception, $statusCode, $headers);
31+
$e->context = $exception->getContext();
32+
33+
return $e;
2234
}
2335

24-
$e = parent::create($exception, $statusCode, $headers);
25-
$e->context = $exception->getContext();
36+
$resolvedStatusCode = $exception instanceof HttpExceptionInterface
37+
? $exception->getStatusCode()
38+
: ($statusCode ?? 500);
39+
40+
$publicMessage = match (true) {
41+
$resolvedStatusCode >= 500 => 'exception.general_500',
42+
403 === $resolvedStatusCode => 'exception.general_403',
43+
404 === $resolvedStatusCode => 'exception.general_404',
44+
default => 'exception.general',
45+
};
46+
47+
$e = parent::createFromThrowable($exception, $resolvedStatusCode, $headers);
48+
$e->context = new ExceptionContext(
49+
publicMessage: $publicMessage,
50+
debugMessage: $exception->getMessage(),
51+
statusCode: $resolvedStatusCode,
52+
);
2653

2754
return $e;
2855
}

templates/exception.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
{% block content_footer_wrapper '' %}
88
{% block main %}
99
<div class="error-message">
10-
<h1><twig:ea:Icon name="internal:circle-exclamation" /> {{ block('page_title') }}</h1>
10+
<h1><twig:ea:Icon name="internal:circle-exclamation" /> <span>{{ block('page_title') }}</span></h1>
1111
{{ exception.publicMessage|trans(exception.translationParameters, 'EasyAdminBundle') }}
1212
</div>
1313
{% endblock %}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>{{ 'page_title.exception'|trans({'%count%': 1}, 'EasyAdminBundle') }}</title>
7+
<style>
8+
body { font-family: system-ui, -apple-system, sans-serif; background: #fff; color: #1e293b; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; }
9+
.error-container { text-align: center; max-width: 600px; padding: 2rem; }
10+
h1 { font-size: 3rem; color: #64748b; margin: 0 0 1rem; }
11+
p { font-size: 1.1rem; color: #1e293b; }
12+
@media (prefers-color-scheme: dark) {
13+
body { background: #0a0a0a; color: #d4d4d4; }
14+
h1 { color: #737373; }
15+
p { color: #d4d4d4; }
16+
}
17+
</style>
18+
</head>
19+
<body>
20+
<div class="error-container">
21+
<h1>{{ exception.statusCode }}</h1>
22+
<p>{{ exception.publicMessage|trans(exception.translationParameters, 'EasyAdminBundle') }}</p>
23+
</div>
24+
</body>
25+
</html>

0 commit comments

Comments
 (0)