44use Whoops \Handler \PrettyPageHandler ;
55use Whoops \Handler \JsonResponseHandler ;
66use Illuminate \Support \ServiceProvider ;
7- use Symfony \Component \Debug \ErrorHandler ;
87use Symfony \Component \HttpFoundation \Response ;
98use Symfony \Component \Debug \ExceptionHandler as KernelHandler ;
109
1110class ExceptionServiceProvider extends ServiceProvider {
1211
1312 /**
14- * Start the error handling facilities .
13+ * Register the service provider .
1514 *
16- * @param \Illuminate\Foundation\Application $app
1715 * @return void
1816 */
19- public function startHandling ( $ app )
17+ public function register ( )
2018 {
21- $ this ->setExceptionHandler ($ app ['exception.function ' ]);
22-
23- // By registering the error handler with a level of -1, we state that we want
24- // all PHP errors converted into ErrorExceptions and thrown which provides
25- // a very strict development environment but prevents any unseen errors.
26- $ app ['kernel.error ' ] = ErrorHandler::register (-1 );
19+ $ this ->registerDisplayers ();
2720
28- if (isset ($ app ['env ' ]) and $ app ['env ' ] != 'testing ' )
29- {
30- $ this ->registerShutdownHandler ();
31- }
21+ $ this ->registerHandler ();
3222 }
3323
3424 /**
35- * Register the service provider .
25+ * Register the exception displayers .
3626 *
3727 * @return void
3828 */
39- public function register ()
29+ protected function registerDisplayers ()
4030 {
41- $ this ->registerKernelHandlers ();
42-
43- $ this ->app ['exception ' ] = $ this ->app ->share (function ()
44- {
45- return new Handler ;
46- });
47-
48- $ this ->registerExceptionHandler ();
31+ $ this ->registerPlainDisplayer ();
4932
50- $ this ->registerWhoops ();
33+ $ this ->registerDebugDisplayer ();
5134 }
5235
5336 /**
54- * Register the HttpKernel error and exception handlers .
37+ * Register the exception handler instance .
5538 *
5639 * @return void
5740 */
58- protected function registerKernelHandlers ()
41+ protected function registerHandler ()
5942 {
60- $ app = $ this ->app ;
61-
62- $ this ->app ['kernel.exception ' ] = function () use ($ app )
43+ $ this ->app ['exception ' ] = $ this ->app ->share (function ($ app )
6344 {
64- return new KernelHandler ($ app[ ' config ' ][ ' app .debug ' ]);
65- };
45+ return new Handler ($ app, $ app [ ' exception.plain ' ], $ app [ ' exception .debug ' ]);
46+ }) ;
6647 }
6748
6849 /**
69- * Register the PHP exception handler function .
50+ * Register the plain exception displayer .
7051 *
7152 * @return void
7253 */
73- protected function registerExceptionHandler ()
54+ protected function registerPlainDisplayer ()
7455 {
75- list ($ me , $ app ) = array ($ this , $ this ->app );
76-
77- $ app ['exception.function ' ] = function () use ($ me , $ app )
56+ $ this ->app ['exception.plain ' ] = $ this ->app ->share (function ($ app )
7857 {
79- return function ($ exception ) use ($ me , $ app )
80- {
81- $ response = $ app ['exception ' ]->handle ($ exception );
82-
83- // If one of the custom error handlers returned a response, we will send that
84- // response back to the client after preparing it. This allows a specific
85- // type of exceptions to handled by a Closure giving great flexibility.
86- if ( ! is_null ($ response ))
87- {
88- $ response = $ app ->prepareResponse ($ response , $ app ['request ' ]);
89-
90- $ response ->send ();
91- }
92- else
93- {
94- $ me ->displayException ($ exception );
95- }
96- };
97- };
58+ $ handler = new KernelHandler ($ app ['config ' ]['app.debug ' ]);
59+
60+ return new SymfonyDisplayer ($ handler );
61+ });
9862 }
9963
10064 /**
101- * Register the shutdown handler Closure .
65+ * Register the Whoops exception displayer .
10266 *
10367 * @return void
10468 */
105- protected function registerShutdownHandler ()
69+ protected function registerDebugDisplayer ()
10670 {
107- $ app = $ this ->app ;
71+ $ this ->registerWhoops () ;
10872
109- register_shutdown_function ( function () use ($ app )
73+ $ this -> app [ ' exception.debug ' ] = $ this -> app -> share ( function ($ app )
11074 {
111- set_exception_handler (array (new StubShutdownHandler ($ app ), 'handle ' ));
112-
113- $ app ['kernel.error ' ]->handleFatal ();
75+ return new WhoopsDisplayer ($ app ['whoops ' ]);
11476 });
11577 }
11678
@@ -125,11 +87,10 @@ protected function registerWhoops()
12587
12688 $ this ->app ['whoops ' ] = $ this ->app ->share (function ($ app )
12789 {
128- $ whoops = new \Whoops \Run ;
129-
130- $ whoops ->writeToOutput (false );
131-
132- $ whoops ->allowQuit (false );
90+ // We will instruct Whoops to not exit after it displays the exception as it
91+ // will otherwise run out before we can do anything else. We just want to
92+ // let the framework go ahead and finish a request on this end instead.
93+ with ($ whoops = new \Whoops \Run )->allowQuit (false );
13394
13495 return $ whoops ->pushHandler ($ app ['whoops.handler ' ]);
13596 });
@@ -165,7 +126,13 @@ protected function registerPrettyWhoopsHandler()
165126 {
166127 with ($ handler = new PrettyPageHandler )->setEditor ('sublime ' );
167128
168- if ( ! is_null ($ path = $ me ->resourcePath ())) $ handler ->setResourcesPath ($ path );
129+ // If the resource path exists, we will register the resource path with Whoops
130+ // so our custom Laravel branded exception pages will be used when they are
131+ // displayed back to the developer. Otherwise, the default pages are run.
132+ if ( ! is_null ($ path = $ me ->resourcePath ()))
133+ {
134+ $ handler ->setResourcesPath ($ path );
135+ }
169136
170137 return $ handler ;
171138 };
@@ -178,52 +145,19 @@ protected function registerPrettyWhoopsHandler()
178145 */
179146 public function resourcePath ()
180147 {
181- if (is_dir ($ path = $ this ->app ['path.base ' ].'/vendor/laravel/framework/src/Illuminate/Exception/resources ' ))
182- {
183- return $ path ;
184- }
148+ if (is_dir ($ path = $ this ->getResourcePath ())) return $ path ;
185149 }
186150
187151 /**
188- * Display the given exception .
152+ * Get the Whoops custom resource path .
189153 *
190- * @param \Exception $exception
191- * @return void
192- */
193- public function displayException ($ exception )
194- {
195- if ($ this ->app ['config ' ]['app.debug ' ])
196- {
197- return $ this ->displayWhoopsException ($ exception );
198- }
199-
200- $ this ->app ['kernel.exception ' ]->handle ($ exception );
201- }
202-
203- /**
204- * Display a exception using the Whoops library.
205- *
206- * @param \Exception $exception
207- * @return void
154+ * @return string
208155 */
209- protected function displayWhoopsException ( $ exception )
156+ protected function getResourcePath ( )
210157 {
211- $ response = $ this ->app ['whoops ' ]->handleException ($ exception );
212-
213- with (new Response ($ response , 500 ))->send ();
214- }
158+ $ base = $ this ->app ['path.base ' ];
215159
216- /**
217- * Set the given Closure as the exception handler.
218- *
219- * This function is mainly needed for mocking purposes.
220- *
221- * @param Closure $handler
222- * @return mixed
223- */
224- protected function setExceptionHandler (Closure $ handler )
225- {
226- return set_exception_handler ($ handler );
160+ return $ base .'/vendor/laravel/framework/src/Illuminate/Exception/resources ' ;
227161 }
228162
229163}
0 commit comments