如何将 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}}
我怎样才能在 laravel 5 中实现它。
对不起,我的英语不好,非常感谢。
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);
}
就我个人而言,当我想 return 一个 API 错误时,我使用 App\Exceptions\API\APIError
作为一般异常抛出。相反,您可以只检查请求是否为 AJAX (if ($request->ajax())
),但我认为明确设置 API 异常似乎更清晰,因为您可以扩展 APIError
class 并添加您需要的任何功能。
我早些时候来这里是为了寻找如何在 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
让我的 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());
}
编辑:Laravel 5.6 处理得很好,无需任何更改,只需确保您发送 Accept
header 为 application/json
.
如果你想保留状态码(这对 front-end 方理解错误类型很有用)我建议在你的 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);
}
而不是
if ($request->ajax() || $request->wantsJson()) {...}
使用
if ($request->expectsJson()) {...}
vendor\laravel\framework\src\Illuminate\Http\Concerns\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。
在 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);
}
如果你想得到 json 格式的异常错误,那么
在 App\Exceptions\Handler 打开处理程序 class 并自定义它。
这是 未授权 请求和 未找到 响应
的示例
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);
}
我刚转到 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 中实现它。
对不起,我的英语不好,非常感谢。
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);
}
就我个人而言,当我想 return 一个 API 错误时,我使用 App\Exceptions\API\APIError
作为一般异常抛出。相反,您可以只检查请求是否为 AJAX (if ($request->ajax())
),但我认为明确设置 API 异常似乎更清晰,因为您可以扩展 APIError
class 并添加您需要的任何功能。
我早些时候来这里是为了寻找如何在 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
让我的 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());
}
编辑:Laravel 5.6 处理得很好,无需任何更改,只需确保您发送 Accept
header 为 application/json
.
如果你想保留状态码(这对 front-end 方理解错误类型很有用)我建议在你的 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);
}
而不是
if ($request->ajax() || $request->wantsJson()) {...}
使用
if ($request->expectsJson()) {...}
vendor\laravel\framework\src\Illuminate\Http\Concerns\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。
在 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);
}
如果你想得到 json 格式的异常错误,那么 在 App\Exceptions\Handler 打开处理程序 class 并自定义它。 这是 未授权 请求和 未找到 响应
的示例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);
}