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

Php 如何将Laravel错误响应作为JSON发送,php,laravel,http-error,Php,Laravel,Http Error,我只是移动到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

我只是移动到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 
当我使用Laravel4时,一切都正常,错误是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);
}

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

我之前来这里是为了寻找如何在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状态代码保持在意外的异常上,例如404500 403

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


编辑:Laravel5.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);
}
而不是

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

使用

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

vendor\laravel\framework\src\illumb\Http\Concerns\interacticsWithContentTypes.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处打开处理程序类并对其进行自定义。 以下是未经授权的请求和未找到的响应的示例

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

如果是Laravel5.1,返回应该是“return response()->json($e->getMessage(),422);”这是有效的。当处理代码不存在时,Laravel返回HTTP 500错误,而不管代码中抛出的具体错误。例如,
abort(403)
将为ajax请求返回500个错误。你也有同样的经历吗?这一定是个虫子?这救了我的命。现在是2017年,我仍在使用5.1,因此这对我来说非常有用。在处理FatalErrorException时,我将200传递给了第二个参数,因为我希望用户获得带有有用消息的警报,而不是像内部服务器错误这样的模糊消息。这可以让页面正常呈现,并为用户提供有用的反馈。请解释您的答案,以便OP和未来的读者更好地理解。这非常有效,返回了一个带有堆栈跟踪的巨大json,但很容易在topNice和simple上看到最后一个错误!但是,向客户端显示所有消息是否安全?
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);
}