Laravel & Lumen RESTFul API 扩展包:Dingo API(四) —— 错误和异常响应

    xiaoxiao2021-03-25  66

    在构建API的时候处理错误是一件痛苦的事儿,在Dingo API中,你不需要手动构建错误响应,只需要抛出一个继承自Symfony\Component\HttpKernel\Exception\HttpException的异常,API会自动为你处理这个响应。

    下面是Dingo 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.');         }         // No error, we can continue to update the user as per usual.     }); });

    Dingo API会自动捕获抛出的异常并将其转化为JSON格式,响应的HTTP状态码也会相应更改以匹配这个异常,ConflictHttpException对应的HTTP状态码是409,默认的JSON格式错误信息如下:

    {     "message": "User was updated prior to your request.",     "status_code": 409 }

    1、资源异常

    以下是资源异常,每个异常都会返回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());         }         // Create user as per usual.     }); });

    Dingo API会自动捕获抛出的异常并将其转化为JSON格式,响应的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."         ]     } }

    2、自定义HTTP异常

    你可以创建自定义的HTTP异常,前提是它们继承自Symfony\Component\HttpKernel\Exception\HttpException或者实现了Symfony\Component\HttpKernel\Exception\HttpExceptionInterface接口。

    3、自定义异常响应

    如果你需要自定义异常返回的响应可以注册一个异常处理器:

    app('Dingo\Api\Exception\Handler')->register(function (Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException $exception) {     return Response::make(['error' => 'Hey, what do you think you are doing!?'], 401); });

    现在如果认证失败我们会显示如下JSON格式信息:

    {     "error": "Hey, what do you think you are doing!?" }

    4、表单请求

    如果你使用表单请求,那么需要继承API表单请求基类或者实现自己的类。API请求基类会检查输入请求是否是请求API,如果是的话当验证失败会抛出Dingo\Api\Exception\ValidationHttpException异常。这个异常会被Dingo API渲染并返回错误响应。

    如果你想要实现自己的表单请求,则必须重载failedValidation和failedAuthorization方法,这些方法必须抛出上述其中一种异常而不是Laravel抛出的HTTP异常。

    转载请注明原文地址: https://ju.6miu.com/read-35393.html

    最新回复(0)