如何将Laravel错误响应作为JSON发送


How to send Laravel error responses as JSON

我刚转到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}}

我怎样才能在拉拉威尔5中做到这一点。

很抱歉我英语不好,非常感谢。

我之前来这里搜索如何在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

为了让我的HTTP状态代码保持在意外的异常上,比如404500403…

这就是我使用的(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());
}
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类并添加所需的任何函数。

编辑:Laravel 5.6处理得很好,无需任何更改,只需确保将Accept标头作为application/json发送即可。


如果你想保留状态代码(这将有助于前端了解错误类型),我建议在你的应用程序/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);
}

在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);
}

而不是

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

使用

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

vendor''laravel''framework''src''Illuminate''Http''Consters''InteractsWithContentTypes.php:42

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

我更新了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。

如果您想获得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);
}