If you use Route Model Binding in your API Controllers and the record is not found, it will automatically return the 404 status code with an error message like "No query results for model [App\Models\User] 1". How can you override it?
I'm talking about this Controller example:
VehicleController.php:
public function show(Vehicle $vehicle) { // return the API response with data}
In case of the model is not found in the routes/api.php
based routes, it returns the JSON like this:
{ "message": "No query results for model [App\\Models\\Vehicle] 1", "exception": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException", "file": "/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php", "line": 391, "trace": [ // ... full stack trace of the error ]}
But maybe you want to have another error than "No query results for model [App\Models\Vehicle] 1"?
One reason for this may be just security: this message exposes your back-end Model name and just tells the API consumer that we probably have a Laravel project. So, any information we may hide from the consumer, increases our security, in theory.
To override this message, you need to override the whole NotFoundHttpException
and return your own structure.
For that, we go to the Laravel Exception Handler file that comes by default with Laravel, and add this to the register()
method:
app/Exceptions/Handler.php:
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class Handler extends ExceptionHandler{ public function register() { $this->renderable(function (NotFoundHttpException $e, $request) { if ($request->is('api/v1/vehicles/*')) { // <- Add your condition here return response()->json([ 'message' => 'Vehicle record not found.' ], 404); } }); }}
Now if you have a 404 on Vehicles, it will just return the JSON:
{ "message": "Record not found."}
As you can see, we have an if-statement for the condition on when we want to override the message. It may be a specific endpoint for a specific model, or you may want to do it for the whole api/*
with some generic message.
exactly what I was looking for thanks 🤠
great... thanks for that :)