找不到记录时更改默认错误消息 - Laravel API

Changing default error message when record not found - Laravel API

我正在构建一个简单的 API,其中有一点是当在端点 URL 中输入的 ID 未指向有效记录时,我得到一个标准的 NotFoundHttpException。而且我不知道如何覆盖它以提供我自己的错误消息响应,因为我不想分享我的模型名称等。

端点 Route::get('{mrl}', [MrlController::class, 'show']);

控制器

public function show(Mrl $mrl)
    {
        if ($data = $mrl) {
            return response(['status' => 'ok', 'data' => $data], 200);
        } else {
            return response(['status' => 'error', 'message' => 'Could not retrieve data'], 500);
        }
    }

当我 运行 当记录存在时,我收到以下内容,这正是我所期望的。

{
    "status": "ok",
    "data": {
        "id": 98,
        "market_id": 1,
        "crop_id": 2,
        "chemical_id": 113,
        "maximum_residue_level": null,
        "exempt": 0,
        "comments": null,
        "date_verified": "2021-10-07",
        "created_at": "2021-10-19T05:42:12.000000Z",
        "updated_at": "2021-10-19T05:42:12.000000Z"
    }
}

但是,当我在路由端点中为不存在的记录输入 ID 时,我收到以下信息:

{
    "message": "No query results for model [App\Seasonal\Mrl] 99"
}

根据我的理解,这是自动查找路由和控制器之间的记录,我不知道如何自定义此行为。

在此先感谢您的帮助!

您没有显示从数据库中获取模型的代码,但我们可以这样假设:

$mrl = Mrl::findOrFail($id);
show($mrl);

模型findOrFail()方法在找不到模型时会抛出异常,方便你适配响应时

你可以这样想象:

try {
    $mrl = Mrl::findOrFail($id);
    return response(['status' => 'ok', 'data' => $data], 200);
} catch (ModelNotFoundException $e) {
    return response(['status' => 'error', 'message' => 'Could not retrieve data'], 500);
}

想法是捕获模型抛出的错误以更改响应的消息和状态代码。

构建 API 时,您应该为任何未处理的错误添加“通用”catch 语句,以显示标准化的通用错误消息并记录发生的情况,如下所示:

try {
    $mrl = Mrl::findOrFail($id);

    // Do more things that could generate errors ?

    return response(['status' => 'ok', 'data' => $data], 200);
} catch (ModelNotFoundException $e) {

    // Not found
    return response(['status' => 'error', 'message' => 'Could not retrieve data'], 500);
} catch (\Exception $e) {

    // Generic error
    \Log::error($e);
    return response(['status' => 'error', 'message' => 'An error occured'], 500);

}

在花时间阅读文档后,我终于找到了如何在使用 Eloquents 路由模型绑定时找到记录时自定义行为的答案。

In the Laravel docs,有一个方法可以实现这个明确的目的,当绑定模型没有有效记录时覆盖默认行为。

这样做的方法是将 ->missing() 函数调用链接到路由的末尾,然后为您希望提供的响应提供行为。如下:

Route::get('{mrl}', [MrlController::class, 'show'])->missing(function () {
    return response(['status' => 'error', 'message' => 'Invalid query.'], 404);
});

将此方法链接到我的请求使我能够 return 我在查询无效模型记录时希望得到的通用响应。