在 App\Exceptions\Handler.php 的 render() 方法中使用 $exception 变量时出现致命错误

Posted

技术标签:

【中文标题】在 App\\Exceptions\\Handler.php 的 render() 方法中使用 $exception 变量时出现致命错误【英文标题】:Fatal Error on using $exception variable in render() Method in App\Exceptions\Handler.php在 App\Exceptions\Handler.php 的 render() 方法中使用 $exception 变量时出现致命错误 【发布时间】:2020-10-03 11:50:01 【问题描述】:

我是 Laravel 新手,遇到了关于 Handler.php 文件的问题。

我正在尝试创建一个接受异常并将其转换为 JSON 响应的类。 可悲的是,在调用构造函数时会抛出一系列错误: (ErrorErrorErrorErrorErrorErrorErrorErrorErrorErrorErrorSymfony\Component\ErrorHandler\Error\FatalError)

我的代码: Handler.php 中的 render():

public function render($request, Throwable $exception)

    $errorResource = new ErrorResource($exception);
    return $errorResource->getJsonResponse();

ErrorResource.php 中的类 ErrorResource:

<?php

namespace Transformers;

use Throwable;

class ErrorResource

    private $exception;

    private $defaultCodes = [TypeError::class => 400];

    private $defaultMessages = [TypeError::class => 'Untgültige URL Parameter'];

    function __construct(Throwable $exception)
    
        $this->exception = $exception;
    

    public function getJsonResponse($exception)
    
        $codeToThrow = 500;
        $messageToThrow = "Internal Server Error";
        $type = get_class($this->exception);

        if (empty($exception->getCode())) 
            $codeToThrow = $this->defaultCodes[$type];
         else 
            $codeToThrow = $exception->getCode();
        
        if (empty($exception->getMessage())) 
            $messageToThrow = $this->defaultMessages[$type];
         else 
            $messageToThrow = $exception->getMessage();
        
        return response()->json(array(
            'Type' => $type,
            'Message' => $messageToThrow
        ), $codeToThrow);
    


我还尝试将 getJsonResponse() 方法移动到 Handler.php 文件并从那里调用它,但没有任何运气。 我真的很困惑为什么我不能用 $exception 变量做某些事情(我也试图创建这个对象的克隆 - 但发生了同样的错误)

希望你能帮我解决这个问题,

问候,

弗朗茨

【问题讨论】:

你只需要return json_encode($exception) 请发布您可以在日志中找到的异常,因为有更多信息 这样做的问题是,如果您的ErrorResource 中有错误,它将引发一个新异常,该异常将调用ErrorResource,这将引发一个新异常并且(我可以复制-粘贴更多,但你明白了)。包装你的 getJsonResponse 并记录你得到的异常而不重新抛出它以防止这种递归。然后检查你的日志,看看你的代码到底有什么问题(乍一看,当$type 不在那个数组中时,它可能是$this-&gt;defaultCodes[$type] @apokryfos 我的代码一切都很好(至少考虑到你提到的问题)。 getJsonResponse() 方法中没有抛出异常,因为代码在调用构造函数时会抛出异常。 @Berto99 - 感谢您指出,laravel 提供了一个日志 - 我不知道。这是调用构造函数时发生的异常([2020-06-13 19:46:25] local.ERROR: Trying to clone an uncloneable object of class TypeError "exception":"[object] (Error(code : 0): 试图在 C:\\xampp\\htdocs\\TNT_Homepage\\TNT-Backend_v2\\app\\Exceptions\\Handler.php:70) [stacktrace]) 处克隆 TypeError 类的不可克隆对象。我认为是调用构造函数的时候,php是在试图克隆对象,导致报错。 【参考方案1】:

问题是,PHP 是按值调用的。这就是为什么它隐式地试图克隆一个不可克隆的对象 -> 错误。要解决此问题,可以使用包装对象,但我决定简单地使用按引用调用 (https://www.javatpoint.com/php-call-by-reference)

【讨论】:

以上是关于在 App\Exceptions\Handler.php 的 render() 方法中使用 $exception 变量时出现致命错误的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.8 到 6.x 升级错误 - App\Exceptions\Handler::renderHttpException 声明

从 laravel 5 升级到 laravel 5.5 导致错误参数 1 传递给 App\Exceptions\Handler::report()

处理程序类中的错误 - Laravel

laravel5异常及时通知

laravel 判断 改了哪个定位

在 Lumen 中创建自定义错误页面