11
11
12
12
namespace Symfony \Bundle \TwigBundle \Controller ;
13
13
14
+ use Symfony \Component \ErrorHandler \ErrorRenderer \ErrorRenderer ;
15
+ use Symfony \Component \ErrorHandler \ErrorRenderer \HtmlErrorRenderer ;
16
+ use Symfony \Component \ErrorHandler \ErrorRenderer \JsonErrorRenderer ;
17
+ use Symfony \Component \ErrorHandler \ErrorRenderer \TxtErrorRenderer ;
18
+ use Symfony \Component \ErrorHandler \ErrorRenderer \XmlErrorRenderer ;
19
+ use Symfony \Component \ErrorHandler \Exception \ErrorRendererNotFoundException ;
14
20
use Symfony \Component \ErrorHandler \Exception \FlattenException ;
15
21
use Symfony \Component \HttpFoundation \Request ;
16
22
use Symfony \Component \HttpFoundation \Response ;
17
- use Symfony \Component \HttpKernel \Log \DebugLoggerInterface ;
18
23
use Twig \Environment ;
19
24
use Twig \Error \LoaderError ;
20
25
use Twig \Loader \ExistsLoaderInterface ;
@@ -30,15 +35,22 @@ class ExceptionController
30
35
{
31
36
protected $ twig ;
32
37
protected $ debug ;
38
+ private $ errorRenderer ;
33
39
34
40
/**
35
41
* @param Environment $twig
36
42
* @param bool $debug Show error (false) or exception (true) pages by default
37
43
*/
38
- public function __construct (Environment $ twig , bool $ debug )
44
+ public function __construct (Environment $ twig , bool $ debug, ErrorRenderer $ errorRenderer = null )
39
45
{
40
46
$ this ->twig = $ twig ;
41
47
$ this ->debug = $ debug ;
48
+ $ this ->errorRenderer = $ errorRenderer ?? new ErrorRenderer ([
49
+ new HtmlErrorRenderer ($ debug ),
50
+ new JsonErrorRenderer ($ debug ),
51
+ new XmlErrorRenderer ($ debug ),
52
+ new TxtErrorRenderer ($ debug ),
53
+ ]);
42
54
}
43
55
44
56
/**
@@ -49,26 +61,12 @@ public function __construct(Environment $twig, bool $debug)
49
61
* be used.
50
62
*
51
63
* @return Response
52
- *
53
- * @throws \InvalidArgumentException When the exception template does not exist
54
64
*/
55
- public function showAction (Request $ request , FlattenException $ exception, DebugLoggerInterface $ logger = null )
65
+ public function showAction (Request $ request , FlattenException $ exception )
56
66
{
57
- $ currentContent = $ this ->getAndCleanOutputBuffering ($ request ->headers ->get ('X-Php-Ob-Level ' , -1 ));
58
- $ showException = $ request ->attributes ->get ('showException ' , $ this ->debug ); // As opposed to an additional parameter, this maintains BC
59
-
60
- $ code = $ exception ->getStatusCode ();
61
-
62
- return new Response ($ this ->twig ->render (
63
- (string ) $ this ->findTemplate ($ request , $ request ->getRequestFormat (), $ code , $ showException ),
64
- [
65
- 'status_code ' => $ code ,
66
- 'status_text ' => isset (Response::$ statusTexts [$ code ]) ? Response::$ statusTexts [$ code ] : '' ,
67
- 'exception ' => $ exception ,
68
- 'logger ' => $ logger ,
69
- 'currentContent ' => $ currentContent ,
70
- ]
71
- ), 200 , ['Content-Type ' => $ request ->getMimeType ($ request ->getRequestFormat ()) ?: 'text/html ' ]);
67
+ return new Response ($ this ->render ($ exception , $ request ), 200 , [
68
+ 'Content-Type ' => $ request ->getMimeType ($ request ->getRequestFormat ())
69
+ ]);
72
70
}
73
71
74
72
/**
@@ -94,32 +92,45 @@ protected function getAndCleanOutputBuffering($startObLevel)
94
92
* @param bool $showException
95
93
*
96
94
* @return string
95
+ *
96
+ * @deprecated since Symfony 4.4
97
97
*/
98
98
protected function findTemplate (Request $ request , $ format , $ code , $ showException )
99
99
{
100
- $ name = $ showException ? 'exception ' : 'error ' ;
101
- if ($ showException && 'html ' == $ format ) {
102
- $ name = 'exception_full ' ;
100
+ @trigger_error (sprintf ('The "%s()" method is deprecated since Symfony 4.4, use "findTwigTemplate()" method instead. ' , __METHOD__ ), E_USER_DEPRECATED );
101
+
102
+ if ($ template = $ this ->findTwigTemplate ($ code , $ format , $ showException )) {
103
+ return $ template ;
103
104
}
104
105
106
+ // default to a generic HTML exception
107
+ $ request ->setRequestFormat ('html ' );
108
+
109
+ return sprintf ('@Twig/Exception/%s.html.twig ' , $ showException ? 'exception_full ' : 'error ' );
110
+ }
111
+
112
+ protected function findTwigTemplate (int $ statusCode , string $ format , bool $ showException ): ?string
113
+ {
105
114
// For error pages, try to find a template for the specific HTTP status code and format
106
115
if (!$ showException ) {
107
- $ template = sprintf ('@Twig/Exception/%s%s .%s.twig ' , $ name , $ code , $ format );
116
+ $ template = sprintf ('@Twig/Exception/error%s .%s.twig ' , $ statusCode , $ format );
108
117
if ($ this ->templateExists ($ template )) {
109
118
return $ template ;
110
119
}
111
120
}
112
121
122
+ $ name = 'error ' ;
123
+ if ($ showException ) {
124
+ $ name = 'html ' === $ format ? 'exception_full ' : 'exception ' ;
125
+ }
126
+
113
127
// try to find a template for the given format
114
128
$ template = sprintf ('@Twig/Exception/%s.%s.twig ' , $ name , $ format );
115
129
if ($ this ->templateExists ($ template )) {
116
130
return $ template ;
117
131
}
118
132
119
- // default to a generic HTML exception
120
- $ request ->setRequestFormat ('html ' );
121
-
122
- return sprintf ('@Twig/Exception/%s.html.twig ' , $ showException ? 'exception_full ' : $ name );
133
+ return null ;
123
134
}
124
135
125
136
// to be removed when the minimum required version of Twig is >= 3.0
@@ -141,4 +152,32 @@ protected function templateExists($template)
141
152
142
153
return false ;
143
154
}
155
+
156
+ private function render (FlattenException $ exception , Request $ request ): string
157
+ {
158
+ $ statusCode = $ exception ->getStatusCode ();
159
+ $ logger = $ request ->attributes ->get ('logger ' );
160
+ $ showException = $ request ->attributes ->get ('showException ' , $ this ->debug );
161
+ $ currentContent = $ this ->getAndCleanOutputBuffering ($ request ->headers ->get ('X-Php-Ob-Level ' , -1 ));
162
+
163
+ $ template = $ this ->findTwigTemplate ($ statusCode , $ request ->getRequestFormat (), $ showException );
164
+
165
+ if (null === $ template ) {
166
+ try {
167
+ // fallback to the native renderer system
168
+ return $ this ->errorRenderer ->render ($ exception , $ request ->getRequestFormat ());
169
+ } catch (ErrorRendererNotFoundException $ e ) {
170
+ $ request ->setRequestFormat ('html ' );
171
+ $ template = sprintf ('@Twig/Exception/%s.html.twig ' , $ showException ? 'exception_full ' : 'error ' );
172
+ }
173
+ }
174
+
175
+ return $ this ->twig ->render ($ template , [
176
+ 'status_code ' => $ statusCode ,
177
+ 'status_text ' => Response::$ statusTexts [$ statusCode ] ?? '' ,
178
+ 'exception ' => $ exception ,
179
+ 'logger ' => $ logger ,
180
+ 'currentContent ' => $ currentContent ,
181
+ ]);
182
+ }
144
183
}
0 commit comments