错误异常和错误响应
创建一个 API 的时候处理错误是很痛苦的。为了避免手动的创建错误响应,你可以简单的抛出一个继承了 Symfony\Component\HttpKernel\Exception\HttpException
的异常,API 会自动的为你处理响应。
这里是 Symfony 内置的异常列表。
异常 | 状态码 |
---|---|
Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException | 403 |
Symfony\Component\HttpKernel\Exception\BadRequestHttpException | 400 |
Symfony\Component\HttpKernel\Exception\ConflictHttpException | 409 |
Symfony\Component\HttpKernel\Exception\GoneHttpException | 410 |
Symfony\Component\HttpKernel\Exception\HttpException | 500 |
Symfony\Component\HttpKernel\Exception\LengthRequiredHttpException | 411 |
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException | 405 |
Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException | 406 |
Symfony\Component\HttpKernel\Exception\NotFoundHttpException | 404 |
Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException | 412 |
Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException | 428 |
Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException | 503 |
Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException | 429 |
Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException | 401 |
Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException | 415 |
比如,当你修改一个记录后,其他的用户已经在你之前修改了它,你可能会抛出一个 ConflictHttpException 异常。
$api->version('v1', function ($api) {
$api->put('user/{id}', function ($id) {
$user = User::find($id);
if ($user->updated_at -> app('request')->get('last_updated')) {
throw new Symfony\Component\HttpKernel\Exception\ConflictHttpException('User was updated prior to your request.');
}
// 没有错误,我们可以继续按照惯例更新用户。
});
});
这个包会自动的捕捉异常,然后转换为 JSON。响应的 HTTP 状态码也会根据异常而改变。如果你没有改变默认的错误格式, ConflictHttpException
异常将默认返回的结果为,HTTP 409 状态码和响应的 JSON 表述 。
{
"message": "User was updated prior to your request.",
"status_code": 409
}
资源异常
下面是通用的资源异常的列表,它们都会返回 HTTP 422 状态码。
Dingo\Api\Exception\DeleteResourceFailedException
Dingo\Api\Exception\ResourceException
Dingo\Api\Exception\StoreResourceFailedException
Dingo\Api\Exception\UpdateResourceFailedException
这些异常是特殊的,因为它们允许你传递任何验证错误,当你尝试去创建、更新或者删除资源的时候。
举一个例子,当你尝试验证新用户的创建时遇到错误时,你可能会抛出StoreResourceFailedException
。
$api->version('v1', function ($api) {
$api->post('users', function () {
$rules = [
'username' => ['required', 'alpha'],
'password' => ['required', 'min:7']
];
$payload = app('request')->only('username', 'password');
$validator = app('validator')->make($payload, $rules);
if ($validator->fails()) {
throw new Dingo\Api\Exception\StoreResourceFailedException('Could not create new user.', $validator->errors());
}
// 按照惯例创建用户。
});
});
这个包会自动的捕获这些异常,转换为 JSON 的表述。响应的 HTTP 状态码也会根据异常而改变。资源异常返回的结果为 HTTP 422 状态码和响应的 JSON 表述。
{
"message": "Could not create new user.",
"status_code": 422,
"errors": {
"username": [
"The username field is required."
],
"password": [
"The password field is required."
]
}
}
自定义 HTTP 异常
你可以创建你自己的 HTTP 异常,只要它们继承了 Symfony\Component\HttpKernel\Exception\HttpException
或者实现了 Symfony\Component\HttpKernel\Exception\HttpExceptionInterface
接口。
自定义异常响应
如果你需要自定义异常的响应,你可以注册一个自定义错误 handler。
app('Dingo\Api\Exception\Handler')->register(function (Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException $exception) {
return Response::make(['error' => 'Hey, 你这是要干嘛!?'], 401);
});
现在如果验证错误,我们会用下面的 JSON 表述呈现。
{
"error": "Hey, 你这是要干嘛!?"
}
表单请求
如果你正在使用表单请求,那么你不仅需要继承基本的 API 表单请求类,还需要实现你自己的。基础 API 表单请求类将会
检查传入的请求是否用于 API,如果是,当验证失败时将抛出 Dingo\Api\Exception\ValidationHttpException
异常。
这个异常将会被正确的渲染,然后返回错误响应。
如果你喜欢实现自己的表单请求,你 必须 重写 failedValidation
和 failedAuthorization
方法。这些方法 必须 抛出上面提到的异常中的一个,而且不是 Laravel 抛出的 HTTP 异常。