Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jmfs's avatar
Level 6

Where to handle 404 for Route Model Binding when model not found

I have route-model binding set up:

// bind news using slug
$router->bind('newsslug', function($slug) {
    return NewsPost::slug($slug)->first();
});

but if the slug is bad, I'll get a null value for my model, which means I want ot give the user a 404 - bad url. If I use firstOrFail(), I get:

No query results for model [App\NewsPost].

so what's the best way to handle a 404 in this case - in the model binding:

$post = NewsPost::slug($slug)->get();
if ($post->isEmpty()) abort(404);
return $post->first();

or in the controller, or in an another way? Thanks...

0 likes
15 replies
bobbybouwmann's avatar

There are multiple ways of doing it, but this is the easiest. You can find a Handler class in app\Exceptions and you can handle it there, for example

public function render($request, Exception $e)
{   
    if ($e instanceof ModelNotFoundException)
    {
        // Do your stuff here
        return response()->view('errors.'.'404');
    }
    elseif ($this->isHttpException($e))
    {
        return $this->renderHttpException($e);
    }
    else
    {
        return parent::render($request, $e);
    }
}
1 like
bestmomo's avatar

It's what I use :

public function render($request, Exception $e)
{
    if($e instanceof ModelNotFoundException)
    {
        abort(404);
    }
    return parent::render($request, $e);
}

And view in resources/views/errors/404.blade.php is showed for error.

@blackbird I think you missed a commit ;)

jmfs's avatar
Level 6

Ah, nice. So if I do:

if ($e instanceof ModelNotFoundException) {
    abort(404);
}

I'm curious how that will impact my site in other ways, as it won't be an error specific to a model-route binding. It could be triggered from a bad relationship or somewhere else, and it would say a 404 error.

bestmomo's avatar

It will be triggered for methods like findOrFail and firstOrFail.

Jeijones's avatar

Hey guys, Maybe you'll be able to help me, I hope :) I have an url like: http://mysite.app/post/a-single-article-in-my-database

But If I change the Slug of my url manually, I still get the error model.

I'm using the method firstOrFail:

$post = Post::where('slug', $slug)->firstOrFail();

An idea to handle this problem?

bobbybouwmann's avatar

@Jeijones First of all, create your own thread if you have another question ;) Now for you problem this should work! Are you sure there is a post with that slug?

pmall's avatar

I'm curious how that will impact my site in other ways, as it won't be an error specific to a model-route binding. It could be triggered from a bad relationship or somewhere else, and it would say a 404 error.

With APP_DEBUG env var to false (production env) a 500 response is returned in case of exception, no user will ever see whats happened.

juanmb's avatar

Ok, I know this post is old and all that. BUT just in case anyone (like myself) falls into this thread, I think that a possible solution may be peeking into the stack trace of the exception using Exception->getTrace(). If you take a look at the file key of the array in position 0 of the stack trace its value is the filename ImplicitRouteBinding.

array:42 [▼
  0 => array:6 [▼
    "file" => "/var/www/sites/tfg/vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.php"
    "line" => 32
    "function" => "firstOrFail"
    "class" => "Illuminate\Database\Eloquent\Builder"
    "type" => "->"
    "args" => []
  ]
...
]

You could use this to filter the exceptions.

1 like
ndotie's avatar

That means, you're requesting model injection of instance which doesnt exist, i.e no such id record on database The id that you pass as parameter does not exist on database

1 like

Please or to participate in this conversation.