Laravel API: Переопределе­ние Сообщения об Ошибке 404

Источник: «Laravel API: Override 404 Error Message in Route Model Binding»
Если вы используете привязку модели к маршруту в API Контроллерах и запись не найдена, она автоматически вернёт статус код 404 с сообщением об ошибке, например No query results for model [App\Models\User] 1. Как это изменить?

Я говорю об этом примере Контроллера:

VehicleController.php:

public function show(Vehicle $vehicle) {
// вернуть API ответ с данными
}

Если модель не найдена в маршрутах основанных на routes/api.php, она возвращает JSON подобный этому:

{
"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": [
// ... полная трассировка стека ошибки
]
}

Но, может быть вы хотите получить другую ошибку, а не No query results for model [App\Models\Vehicle] 1?

Одной из причин может быть просто безопасность: сообщение об ошибке раскрывает имя Модели и сообщает API потребителю, что у нас, вероятно, Laravel проект. Таким образом, любая информация, которую можем скрыть от потребителя, теоретически повышает безопасность.

Чтобы переопределить это сообщение, нужно переопределить всё исключение NotFoundHttpException и вернуть собственную структуру.

Для этого мы переходим к файлу обработчику исключений Laravel, который по умолчанию поставляется вместе с Laravel, и добавляем в него метод register():

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/*')) { // <- Добавьте своё условие здесь
return response()->json([
'message' => 'Vehicle record not found.'
], 404);
}
});
}
}

Теперь, при ошибке 404 для Vehicles, он просто вернёт JSON:

{
"message": "Record not found."
}

Как видите, у нас есть if для условия, когда мы хотим переопределить сообщение. Это может быть конкретная конечная точка для конкретной модели, или можно сделать для всего api/* с общим сообщением.

Дополнительные материалы

Предыдущая Статья

Laravel: Ошибки связанные с мутабельностью Carbon

Следующая Статья

Laravel: Используем PHP Codesniffer