如何以 JSON 格式发送 Laravel 错误响应
Posted
技术标签:
【中文标题】如何以 JSON 格式发送 Laravel 错误响应【英文标题】:How to send Laravel error responses as JSON 【发布时间】: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 中实现这一点。
对不起,我的英语不好,非常感谢。
【问题讨论】:
【参考方案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.php
的render
方法中
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);
【讨论】:
以上是关于如何以 JSON 格式发送 Laravel 错误响应的主要内容,如果未能解决你的问题,请参考以下文章
如何通过ajax fetch api响应将从laravel控制器接收到的数据发送到另一个页面