laravel里的这几种错误提示有什么区别啊?

我正在学习怎么做app接口,发现有3种方式可以返回错误信息,三种有什么区别呢?

第一种:

abort(403, '验证码已失效');

第一种返回值:

{
    "message": "验证码已失效",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\HttpException",
    "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/Application.php",
    "line": 1116,
    "trace": [
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php",
            "line": 44,
            "function": "abort",
            "class": "Illuminate\\Foundation\\Application",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/app/Http/Controllers/Api/UsersController.php",
            "line": 22,
            "function": "abort"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Controller.php",
            "line": 54,
            "function": "store",
            "class": "App\\Http\\Controllers\\Api\\UsersController",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php",
            "line": 45,
            "function": "callAction",
            "class": "Illuminate\\Routing\\Controller",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
            "line": 254,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\ControllerDispatcher",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
            "line": 197,
            "function": "runController",
            "class": "Illuminate\\Routing\\Route",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 695,
            "function": "run",
            "class": "Illuminate\\Routing\\Route",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 128,
            "function": "Illuminate\\Routing\\{closure}",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php",
            "line": 50,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 127,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 63,
            "function": "handleRequest",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 127,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 103,
            "function": "handleRequest",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 55,
            "function": "handleRequestUsingNamedLimiter",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/app/Http/Middleware/AcceptHeader.php",
            "line": 13,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "App\\Http\\Middleware\\AcceptHeader",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 103,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 697,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 672,
            "function": "runRouteWithinStack",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 636,
            "function": "runRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 625,
            "function": "dispatchToRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 166,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 128,
            "function": "Illuminate\\Foundation\\Http\\{closure}",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php",
            "line": 31,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php",
            "line": 40,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
            "line": 27,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php",
            "line": 86,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/fruitcake/laravel-cors/src/HandleCors.php",
            "line": 57,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Fruitcake\\Cors\\HandleCors",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/fideloper/proxy/src/TrustProxies.php",
            "line": 57,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 167,
            "function": "handle",
            "class": "Fideloper\\Proxy\\TrustProxies",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 103,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 141,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 110,
            "function": "sendRequestThroughRouter",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/www/wwwroot/sm.com/public/index.php",
            "line": 52,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        }
    ]
}

第一种代码里貌似设置了状态码,但是返回的数据的时候会等待很久,我在postman里倒是注意都有一个地方显示的Status:403Forbidden,但是请求时间用了15s,15s以后出来的返回信息里面没有403这个值啊,前端要怎么使用这个状态呢?


第二种:

throw new AuthenticationException('验证码错误')

第二种要怎么自定义状态码呢?和第一种有什么区别,什么情况下用呢?


第三种:

return response()->json([
                'Status_code' => 401,
                'msg' => '验证码错误'
            ])->setStatusCode(201);

第三种是最直观的,但是我在最后单独写了->setStatusCode(201);,不过貌似和第一种有一样的困惑,所有我又在json里单独设置了,所以我的问题是->setStatusCode(201);是干嘛的,app前端的同学要怎么用?

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
最佳答案

第一种,abort函数是Laravel给用户提供的、可快速指定HTTP状态码返回字符串的快捷方法。可以跳进去看该函数具体做了什么。

对于第二种,自己创建不同的异常,在具体的异常类里可以存返回时的HTTP状态码。

然后在app\Exception\Handler.php里判断异常类是否有状态码的属性,有该属性的话获取并在输出响应时指定状态码。为了应对语言默认的异常类,需要做兼容处理。哪个默认异常类返回哪个状态码。

对于第三种,json里返回的内容对浏览器来说就是纯字符串。而后面的setStatusCode是浏览器能接受到的HTTP状态码。浏览器会在必要的时候做特殊处理,例如http状态码是301的话会跳转请求另一个URL。在JSON里返回status_code:301,浏览器是不会去处理的。

前端同学是能获取HTTP状态码的,你们协商好具体状态码表示什么样的情况,前端同学做好相应处理即可。

2年前 评论
讨论数量: 7

答案是最终响应http没区别,都是http状态码+响应数据,但是对于前端可以选择可解析的相应数据,例如json,而不是html,并且Exception还可以捕捉,做定制化响应!看你业务需求选择,api和web按需选择!

2年前 评论
wongvio (楼主) 2年前

你得区分清楚,什么是HTTP状态码,什么是业务状态码。至于你们团队想用哪一种状态码,自行统一协商即可。
HTTP状态码是有业界标准,可用码数量范围比较少。自定义业务状态码,可灵活定义,目前我个人比较多采用这种。
HTTP状态码,是HTTP协议的一部分,一个标准的HTTP响应报文,可能是如下形式:

HTTP/1.1 200 OK
Server: nginx
Date: Mon, 20 Feb 2017 09:13:59 GMT
Content-Type: application/json;charset=UTF-8

{"code":"401","message":"Authorization failed by filter.","data":[]}

那么这个报文里,200就是所谓的“HTTP状态码”,401就是所谓的“业务状态码”。
具体使用哪个码,没有说一个绝对的优劣,只在于团队形成统一规范,方便对接。

2年前 评论

@wongvio AuthenticationException只是一个异常,没有状态码,但是框架在组装响应的时候会添加上401,abort的第一个参数就是响应码!

class AuthenticationException extends Exception
2年前 评论

这有是区别 没啥区别 第二种自己统一在ExceptionHandle了面catch一下 然后根据自己的业务统一返回。推荐第二种做法,代码会比较直观优雅,统一处理,也遵循异常向上抛出,同意处理的原则!

2年前 评论
  1. Status_code 为 自定义状态码 这是和前端协定的业务状态码
  2. http状态码 列些简单的
    • 200 正常响应
    • 401 请求需要认证
    • 403 请求被拒绝
    • 404 资源未找到
    • 500 服务器故障
    • 502 网关错误 一般为nginx、apache 等应用服务的问题
    • 503 服务器停机维护

->setStatusCode(200)方法是http状态码 这是http协议的状态码 前端可以通过全局拦截器处理

//前端处理
// 响应拦截器
axios.interceptors.response.use(
response => {
        // 如果返回的http状态码为200、201,说明接口请求成功,可以正常拿到数据 然后根据 业务状态码 处理数据
        // 否则的话抛出错误

        if (response.status === 200) {
            return Promise.resolve(response);
        } else {
          //根据 code业务码处理
            return Promise.reject(response);
        }
},
//异常 接受到了异常的`http状态码` 即 401 403 404 500
error => {
       switch (error.response.status) {
                case 401:
                    Cookies.remove('token')
                    Cookies.remove('auth')
                    store.state.auth = false
                    ElMessage.error({
                        message: '登录过期,请重新登录'
                    })
                    break;
   ......
  }
  1. laravel全局异常 app/Exceptions/Handler.php 目录下
    • 可参考我的写法

目录

app
├── Exceptions
│   └── Handler.php

定义全局异常代码

 public function render($request, Throwable $exception)
    {
        if(Str::lower($request->segment(1)) === 'api'){
            if ($exception instanceof ValidationException) {
                return $this->fail($exception->validator->errors()->first(),$exception->errors(),10002,$exception->status);
            } elseif ($exception instanceof ModelNotFoundException) {
                return $this->fail("一不小心数据走丢了~~~",[],10003,500);
            } else if ($exception instanceof NotFoundHttpException) {
                return $this->fail('路由未找到',[],10004,$exception->getStatusCode());
            } else if ($exception instanceof MethodNotAllowedHttpException) {
                return $this->fail('请求方法不存在',[],10005,$exception->getStatusCode());
            } else if ($exception instanceof UnauthorizedHttpException) { //这个在jwt.auth 中间件中抛出
                return $this->fail('无效的访问令牌',null,10006,401);
            } elseif ($exception instanceof AuthenticationException) { //这个异常在 auth:api 中间件中抛出
                return $this->fail('无效的访问令牌',null,10006,401);
            } elseif ($exception instanceof \Symfony\Component\HttpKernel\Exception\HttpException &&
                $exception->getStatusCode() == 403){
                return $this->fail('没有访问权限,请联系管理员',null,10007,$exception->getStatusCode());
            }
            return $this->fail($exception->getMessage().' '.$exception->getFile(). ' '.$exception->getLine(),null,10001);
        }else{
            return parent::render($request, $exception);
        }
    }
  1. fail 方法 统一将响应封装成一个trait性状类 use关键字继承即可
    /**
      * @param null $data
      * @param string $msg
      * @return \Illuminate\Http\JsonResponse |\Illuminate\Http\Response
      */
     public function fail($message,$data=[], $code = 10001,$httpCode = 500)
     {
         return response()->json(
             [
                 'code' => $code,
                 'message' => $message,
                 'data' => $data,
                 'time' => time()
             ],$httpCode);
     }
  2. 可以看看超哥是怎么理解的一种 Laravel 异常上下文解决方案
2年前 评论

第一种,abort函数是Laravel给用户提供的、可快速指定HTTP状态码返回字符串的快捷方法。可以跳进去看该函数具体做了什么。

对于第二种,自己创建不同的异常,在具体的异常类里可以存返回时的HTTP状态码。

然后在app\Exception\Handler.php里判断异常类是否有状态码的属性,有该属性的话获取并在输出响应时指定状态码。为了应对语言默认的异常类,需要做兼容处理。哪个默认异常类返回哪个状态码。

对于第三种,json里返回的内容对浏览器来说就是纯字符串。而后面的setStatusCode是浏览器能接受到的HTTP状态码。浏览器会在必要的时候做特殊处理,例如http状态码是301的话会跳转请求另一个URL。在JSON里返回status_code:301,浏览器是不会去处理的。

前端同学是能获取HTTP状态码的,你们协商好具体状态码表示什么样的情况,前端同学做好相应处理即可。

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!