Exceptions in Laravel 4
Update: Now the preliminary documentation is out for Laravel 4, it seems there is a simple way to throw 404 errors:
<?php
App::abort(404);
You can then catch this error by registering a missing
handler in app/start/global.php
:
<?php
App::missing(function($exception) {
return Response::make(
View::make('errors/404')
, 404);
});
However, read on through the original post below for examples on how to register custom Exceptions you can throw to improve your application's flow.
Original Post: Perhaps this will change before Laravel 4 is officially released, but I can't find any simple way to throw, for example, a 404 Not Found exception.
Here's a clean solution.
Create a new file inside app/
named exceptions.php
. In here, we'll define any exceptions. For a small app I'm working on, I require a "Not Found" and "Not Allowed" exceptions:
<?php
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class NotFoundException extends NotFoundHttpException {}
class NotAllowedException extends Exception {}
We now need to load require this file with Composer. Open up composer.json
and under autoload.classmap
, add in app/exceptions.php
, like so:
{
"require": {
"illuminate/foundation": "1.2.*"
},
"autoload": {
"classmap": [
"app/exceptions.php",
"app/controllers",
"app/models",
"app/database/migrations",
"app/tests/TestCase.php"
]
},
"minimum-stability": "dev"
}
Don't forget to composer dumpautoload
from the terminal.
Now you're free to throw your NotFoundException
and NotAllowedException
in your controllers.
<?php
class JobsController extends BaseController {
public function show($id) {
if ( ! $job = Job::find($id)) {
throw new NotFoundException;
}
return View::make('jobs/show')->with('job', $job);
}
}
Finally, we need to define error handlers for these exceptions. Inside app/start/global.php
, add the following inside the "Application Error Handler" section:
<?php
// ...
App::error(function(NotFoundException $exception, $code) {
return Response::make(View::make('errors/404'), 404);
});
App::error(function(NotAllowedException $exception, $code) {
return Redirect::to('/')
->with('error', 'You do not have permission to do that');
});
When a NotFoundException
is thrown, we're displaying the view at app/views/errors/404
. We're passing this through the Response
class so that we can specify the HTTP Status Code as 404.
When a NotAllowedException
is thrown, we're redirecting back to the home page, with an error message.
There's a debate over whether you should raise exceptions as part of your application flow. Personally, I'm a fan of it for this use-case.