2

I'm trying to create a default route in my Laravel 4 REST API, that hits, when none of my other defined routes matches the request, to return a specific error to the caller.

Is this possible? Unfortunately, I found nothing in the docs, so I played around and tried using a wildcard (*) as the last Route definition in my routes.php but that doesn't work.

Route::when("*", function(){
    throw new CustomizedException('Route not found...');
});

When I have this route and do an artisan routes, I get an Exception: {"error":{"type":"ErrorException","message":"Object of class Closure could not be converted to string","file":"\/Applications\/MAMP\/htdocs\/CampaigningTools\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Console\/RoutesCommand.php","line":153}}

Calling an inexistent route does not trigger my customized Exception, but the standard one: {"error":{"type":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException","message":"","file":"\/Applications\/MAMP\/htdocs\/CampaigningTools\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Router.php","line":1429}}

I also tried using any as suggested in this post, but that also doesn't work:

Route::any( '(.*)', function( $page ){
    throw new ValidationException('Custom error');
});

This route also doesn't fire, when I call an inexistent route.

Any hints, what I'm doing wrong would be appreciated.

Community
  • 1
  • 1
Stefan S
  • 650
  • 2
  • 10
  • 23

4 Answers4

19

Took me a while to figure this out, actually @devo was very close:

Route::get('{slug}', function($slug) {

    // check your DB for $slug, get the page, etc...

})->where('slug', '^.*');

This will catch the / too. If you'd rather handle the home page separately change the regexp to: where('slug', '^.+');

ivanhoe
  • 4,593
  • 1
  • 23
  • 22
8

If there is no matching route, Laravel throws a "Symfony\Component\HttpKernel\Exception\NotFoundHttpException". You can simply write your own error handler to catch that exception and do something else (have a look at http://laravel.com/docs/errors).

Add one of the following two blocks (e.g. in your "app/start/global.php" in the "Application Error Handler" block):

App::error(function(\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $exception, $code)
{
    // do something
});

Or:

App::missing(function($exception)
{
    // do something
});
pusch
  • 96
  • 2
1

Try something like this,

Route::get('{slug}', function($slug) {
    // get the page from database using Page model
    $page = Page::where('slug', '=', $slug)->first();

    if ( is_null($page) ) {
        return App::abort(404);
    }

    return View::make('page')->with('page',$page);
});

// Show 404 Page

App::missing(function($exception)
{
    return Response::view('errors.missing', array(), 404);
});
Anshad Vattapoyil
  • 23,145
  • 18
  • 84
  • 132
1

Try to put this at the end of your route file?

Route::any( '/{default?}', function( $page ){
    throw new ValidationException('Custom error');
});

Or

Route::any('/{default?}', 'TestController@yourMethod'); // pointing to a method displaying a 404 custom page
Sebastien Horin
  • 10,803
  • 4
  • 52
  • 54