I'm trying to find a way of customising the error handling of Laravel 5.4 when a route can't be found. In my web.php there is a route incorrectly defined (deliberately for testing purposes). I have wrapped it in a try...catch block and thrown my own custom exception RoutesException:
try {
Route::get('terms_rop_labels/view', 'LRChildController@view');
}catch (NotFoundHttpException $ex) {
throw new RoutesException('terms_rop_labels/view');
}
Then in app\Exceptions\Handler.php I am trying to catch the exception in a test view:
if ($exception instanceof NotFoundHttpException) {
$parameters = [
'message'=> 'NotFoundHttpException'
];
return response()->view('errors.test', $parameters, 500);
}
if ($exception instanceof RoutesException) {
$parameters = [
'message'=> 'RoutesException'
];
return response()->view('errors.test', $parameters, 500);
}
Can anyone explain why the handler catches a NotFoundHttpException and not my custom RoutesException?
The route in web.php is not throwing a NotFoundHttpException exception. You are just registering routes in web.php, not resolving them.
The Route facade in web.php is giving you static access to the get method in the Illuminate\Routing\Router class (see lines of 125 - 135 in https://github.com/laravel/framework/blob/5.4/src/Illuminate/Routing/Router.php)
/**
* Register a new GET route with the router.
*
* @param string $uri
* @param \Closure|array|string|null $action
* @return \Illuminate\Routing\Route
*/
public function get($uri, $action = null)
{
return $this->addRoute(['GET', 'HEAD'], $uri, $action);
}
(So you are just adding routes to the RouteCollection with Router get method in the web.php file.)
If you look in the back-trace, you can see where the NotFoundHttpException exception is being thrown in your case. For example, if you were to navigate to a nonexistent route that you have not added to the route collection by registering it in web.php, you would see that the NotFoundHttpException is being thrown by the RouteCollection class match method on line 179.
In your case, the try/catch in not catching a NotFoundHttpException because the
Route::get('terms_rop_labels/view', 'LRChildController@view');
is not throwing the NotFoundHttpException.
Maybe you can achieve what you want by just catching NotFoundHttpException in the app\Exceptions\Handler instead.