【问题标题】:How to send Laravel error responses as JSON如何以 JSON 格式发送 Laravel 错误响应
【发布时间】:2015-04-11 05:54:03
【问题描述】:

我只是移动到 laravel 5 并且我在 HTML 页面中收到来自 laravel 的错误。像这样的:

Sorry, the page you are looking for could not be found.

1/1
NotFoundHttpException in Application.php line 756:
Persona no existe
in Application.php line 756
at Application->abort('404', 'Person doesnt exists', array()) in helpers.php line 

当我使用 laravel 4 时一切正常,错误是 json 格式,这样我就可以解析错误消息并向用户显示消息。 json错误示例:

{"error":{
"type":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException",
"message":"Person doesnt exist",
"file":"C:\\xampp\\htdocs\\backend1\\bootstrap\\compiled.php",
"line":768}}

我如何在 laravel 5 中实现这一点。

对不起,我的英语不好,非常感谢。

【问题讨论】:

    标签: php laravel http-error


    【解决方案1】:

    Laravel 5 在app/Exceptions/Handler.php 中提供了一个异常处理程序。 render 方法可用于以不同方式呈现特定异常,即

    public function render($request, Exception $e)
    {
        if ($e instanceof API\APIError)
            return \Response::json(['code' => '...', 'msg' => '...']);
        return parent::render($request, $e);
    }
    

    就我个人而言,当我想返回 API 错误时,我使用App\Exceptions\API\APIError 作为一般异常来抛出。相反,您可以只检查请求是否为 AJAX (if ($request->ajax())),但我认为显式设置 API 异常似乎更简洁,因为您可以扩展 APIError 类并添加您需要的任何功能。

    【讨论】:

      【解决方案2】:

      我之前来这里是为了寻找如何在 Laravel 的任何地方抛出 json 异常,答案让我走上了正确的道路。对于发现此搜索类似解决方案的任何人,以下是我在应用程序范围内实施的方式:

      将此代码添加到app/Exceptions/Handler.phprender方法中

      if ($request->ajax() || $request->wantsJson()) {
          return new JsonResponse($e->getMessage(), 422);
      }
      

      将此添加到处理对象的方法中:

      if ($request->ajax() || $request->wantsJson()) {
      
          $message = $e->getMessage();
          if (is_object($message)) { $message = $message->toArray(); }
      
          return new JsonResponse($message, 422);
      }
      

      然后在任何你想要的地方使用这段通用代码:

      throw new \Exception("Custom error message", 422);
      

      它会将 ajax 请求后抛出的所有错误转换为 Json 异常,以便以任何你想要的方式使用:-)

      【讨论】:

      • 如果 Laravel 5.1,返回应该是“return response()->json($e->getMessage(), 422);”
      • 这行得通。当处理代码不存在时,Laravel 会返回 HTTP 500 错误,而不管代码中抛出的具体错误是什么。例如。 abort(403) 会为 ajax 请求返回 500 错误。你有同样的经历吗?这一定是个bug?
      • 这救了我的命。现在是 2017 年,我仍在使用 5.1,所以这对我来说真的很有用。在处理 FatalErrorException 时,我将 200 传递给第二个参数,因为我希望用户收到带有有用消息的警报,而不是像 Internal Server Error 这样的晦涩消息。这可以让页面正常呈现并为用户提供有用的反馈。
      【解决方案3】:

      Laravel 5.1

      将我的 HTTP 状态代码保留在意外异常上,例如 404、500 403...

      这是我使用的(app/Exceptions/Handler.php):

       public function render($request, Exception $e)
      {
          $error = $this->convertExceptionToResponse($e);
          $response = [];
          if($error->getStatusCode() == 500) {
              $response['error'] = $e->getMessage();
              if(Config::get('app.debug')) {
                  $response['trace'] = $e->getTraceAsString();
                  $response['code'] = $e->getCode();
              }
          }
          return response()->json($response, $error->getStatusCode());
      }
      

      【讨论】:

        【解决方案4】:

        编辑:Laravel 5.6 处理得非常好,无需任何更改,只需确保您将 Accept 标头发送为 application/json


        如果你想保留状态码(这对前端理解错误类型很有用)我建议在你的 app/Exceptions/Handler.php 中使用它:

        public function render($request, Exception $exception)
        {
            if ($request->ajax() || $request->wantsJson()) {
        
                // this part is from render function in Illuminate\Foundation\Exceptions\Handler.php
                // works well for json
                $exception = $this->prepareException($exception);
        
                if ($exception instanceof \Illuminate\Http\Exception\HttpResponseException) {
                    return $exception->getResponse();
                } elseif ($exception instanceof \Illuminate\Auth\AuthenticationException) {
                    return $this->unauthenticated($request, $exception);
                } elseif ($exception instanceof \Illuminate\Validation\ValidationException) {
                    return $this->convertValidationExceptionToResponse($exception, $request);
                }
        
                // we prepare custom response for other situation such as modelnotfound
                $response = [];
                $response['error'] = $exception->getMessage();
        
                if(config('app.debug')) {
                    $response['trace'] = $exception->getTrace();
                    $response['code'] = $exception->getCode();
                }
        
                // we look for assigned status code if there isn't we assign 500
                $statusCode = method_exists($exception, 'getStatusCode') 
                                ? $exception->getStatusCode()
                                : 500;
        
                return response()->json($response, $statusCode);
            }
        
            return parent::render($request, $exception);
        }
        

        【讨论】:

        • 这很好用,返回一个带有堆栈跟踪的巨大 json,但可以很容易地看到顶部的最后一个错误
        【解决方案5】:

        代替

        if ($request->ajax() || $request->wantsJson()) {...}

        使用

        if ($request->expectsJson()) {...}

        供应商\laravel\framework\src\Illuminate\Http\Concerns\InteractsWithContentTypes.php:42

        public function expectsJson()
        {
            return ($this->ajax() && ! $this->pjax()) || $this->wantsJson();
        }
        

        【讨论】:

        • 解释你的答案,以便 OP 和未来的读者更好地理解。
        【解决方案6】:

        我更新了我的 app/Exceptions/Handler.php 以捕获不是验证错误的 HTTP 异常:

        public function render($request, Exception $exception)
        {
            // converts errors to JSON when required and when not a validation error
            if ($request->expectsJson() && method_exists($exception, 'getStatusCode')) {
                $message = $exception->getMessage();
                if (is_object($message)) {
                    $message = $message->toArray();
                }
        
                return response()->json([
                    'errors' => array_wrap($message)
                ], $exception->getStatusCode());
            }
        
            return parent::render($request, $exception);
        }
        

        通过检查getStatusCode()方法,可以判断异常是否可以成功强制转换为JSON。

        【讨论】:

          【解决方案7】:

          在 Laravel 5.5 上,您可以在 app/Exceptions/Handler.php 中使用 prepareJsonResponse 方法,该方法将强制响应为 JSON。

          /**
           * Render an exception into an HTTP response.
           *
           * @param  \Illuminate\Http\Request  $request
           * @param  \Exception  $exception
           * @return \Illuminate\Http\Response
           */
          public function render($request, Exception $exception)
          {
              return $this->prepareJsonResponse($request, $exception);
          }
          

          【讨论】:

          • 又好又简单!但是,向客户端显示所有这些消息是否安全?
          【解决方案8】:

          如果你想得到 json 格式的异常错误,那么 在 App\Exceptions\Handler 打开 Handler 类并自定义它。 这是未经授权请求和未找到响应

          的示例
          public function render($request, Exception $exception)
          {
              if ($exception instanceof AuthorizationException) {
                  return response()->json(['error' => $exception->getMessage()], 403);
              }
          
              if ($exception instanceof ModelNotFoundException) {
                  return response()->json(['error' => $exception->getMessage()], 404);
              }
          
              return parent::render($request, $exception);
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-08-24
            • 1970-01-01
            • 2016-04-03
            • 2015-06-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多