学 Laravel 和 Vuejs,来 codecasts.com 看高质量视频教程

之前的一篇文章介绍了 Laravel 的异常和日志的一些情况,本文来看看 Laravel 在处理异常返回的时候是什么样的流程。

在 Laravel 的项目中,出现异常的时候,Laravel 会默认去寻找这个类中是否存在 render() 这个方法,因为这个方法是负责处理渲染异常信息的。所以你要自定义异常的返回信息的话,可以直接在 render() 方法里面实现,这都是看你自己的需求。

在通常情况下,Laravel 会自动将异常信息分为两种格式来处理:HTML 或者 JSON。而在这之前,它会把基本所有的异常信息先处理为 HTTPException

if ($e instanceof ModelNotFoundException) {
    $e = new NotFoundHttpException($e->getMessage(), $e);
} elseif ($e instanceof AuthorizationException) {
    $e = new HttpException(403, $e->getMessage());
} elseif ($e instanceof TokenMismatchException) {
    $e = new HttpException(419, $e->getMessage());
}

后面讲一下 Laravel 常见的异常处理。

认证异常处理

认证异常是指Illuminate\Auth\AuthenticationException,这个是由 App\Exceptionsunauthenticated() 方法来处理的。默认情况下,laravel 会将用户重定向到 /login URL 中,但是如果你是期望返回 JSON 数据的话,大概返回的信息如下:

{"message" : "Unauthenticated."}

表单验证异常处理

其实在表单验证不通过的时候,如果我们使用的是传统的重定向到某个页面中,我们通常会使用类似下面的代码来提示错误信息:

@if (count($errors) > 0)
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

其实表单验证出错的时候也是可以直接使用 JSON 的格式返回的,这个时候需要注意的是,返回的 HTTP 状态码是 422

{
  "message": "The given data failed to pass validation.",
  "errors": {
    "name": [
        "The name field is required.",
        "The name field must be a string."
    ]
  }
}

其他的异常处理

目前来说,Laravel 也是直接将大多数的异常转化为 HTTPException,但是某些情况下我们还是需要自己去处理异常的返回信息,这个时候怎么办?

使用 expectsJson() !这个方法可以非常easy地实现我们队 JSON 返回的需求!expectsJson() 主要是通过指定一个特定的 X-Requested-With header 来实现的,如果这个 header 携带 XMLHttpRequest 的值的话,Laravel 就认为我们期望返回的是 JSON 格式的异常信息。如果说你使用 Laravel 推荐的 axios 的话,在 assets 下的 bootstrap.js 文件就可以看到,Laravel 官方就会为你指定这个 header:

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

所以在我们使用expectsJson()返回异常信息的时候,大概的格式是下面这样:

{
    "message": "...",
    "file": "...",
    "line": 0,
    "trace": "..."
}

我们在前端处理的时候通常就是取 message 就好了。

那如果说是正常的 HTML 的返回格式呢?这个时候,其实你就可以在 resources/views/errors 定义一个 500.blade.php 文件,Laravel 会默认先展示这个视图文件的内容。如果没有自定义,那就返回那个常见的 :

Whoops, looks like something went wrong.

总结

Laravel 的异常处理通常会转化为 HTTPException,而且我们在使用 AJAX 的时候也是可以直接用 expectsJson() 来判断返回什么格式的信息。这样基本上解决了 90% 以上的应用场景了。

图片描述

关注 codecasts 公众号,定期送书送福利!


JellyBool
16.2k 声望2k 粉丝

给学网 GeiXue.com 创始人:让每一个热爱编程的人都学有所成的精品课程。