【问题标题】:How to find place in the code where Doctrine's exceptions was raised?如何在代码中找到引发 Doctrine 异常的位置?
【发布时间】:2019-08-20 21:32:58
【问题描述】:

我的代码中某处有 MappingException。请帮助我如何在引发异常的代码中找到位置?

[29-Mar-2019 22:30:26 Europe/Moscow] PHP Fatal error:  Uncaught Doctrine\Common\Persistence\Mapping\MappingException: Class 'Client' does not exist in /var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/MappingException.php:93
Stack trace:
#0 /var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php(24): Doctrine\Common\Persistence\Mapping\MappingException::nonExistingClass('Client')
#1 /var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(251): Doctrine\Common\Persistence\Mapping\RuntimeReflectionService->getParentClasses('Client')
#2 /var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(284): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getParentClasses('Client')
#3 /var/www/virtual/account/htdocs/vendor/doctrine/orm/lib/Doc in /var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/MappingException.php on line 93

如果我会做这样的事情会有所帮助还是我会得到与现在相同的堆栈跟踪?

try {
    // application init
    $app->init();
} catch (Doctrine\Common\Persistence\Mapping\MappingException $e) {
    error_log("MappingException: " . $e->getTraceAsString());
    throw $e;
}

更新

问题与 Doctrine 不完全相关,而是与堆栈跟踪的长度有关,该长度太大并且不适合 1024 字节(默认 php 的设置)。所以,只需要增加堆栈跟踪的最大长度,这可以通过以下命令来完成:

ini_set('log_errors_max_len', 0); // 0 - infinity length allow

【问题讨论】:

  • 我没有使用过教义。但看起来像一个失败的依赖注入。您的任何类是否等待 Client 类的依赖项?
  • 是的,看起来像依赖注入问题,我检查了我所有的实体、存储库和其他所有内容,但没有找到任何东西。我认为现代 ORM 工具应该提供详细的错误报告,其中包括代码中引发异常的位置。

标签: php debugging exception doctrine-orm doctrine


【解决方案1】:

问题与 Doctrine 不完全相关,而是与堆栈跟踪的长度有关,该长度太大并且不适合 1024 字节(默认 php 的设置)。所以,只需要增加堆栈跟踪的最大长度,这可以通过以下命令来完成:

ini_set('log_errors_max_len', 0); // 0 - infinity length allow

【讨论】:

    【解决方案2】:

    异常被抛出:

    文件: /var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/MappingException.php

    第 93 行

    如果您想查看之前发生的事情(原因),您可以检查您的代码跟踪。我没有看到你的完整代码,但是:

    如果你有 Uncaught 异常,即使你用 try catch 块包装你的代码,这里只有两种主要方法:

    1.你没有捕捉到异常。可能是因为没有转义要捕获的异常,或者异常与您尝试捕获的异常不同。或者你重新抛出它(可能是你的情况)

    \Exception尝试这种捕捉方式

    try {
        // application init
        $app->init();
    } catch (\Exception $e) {
        error_log("MappingException: " . $e->getTraceAsString());
        //no throw
    }
    

    如果这可行,那么您可以更改您的代码以采用这种方式捕获异常

    try {
        // application init
        $app->init();
    
    //note backslash
    } catch (\Doctrine\Common\Persistence\Mapping\MappingException $e) {
        error_log("MappingException: " . $e->getTraceAsString());
        //no throw
    
    } catch (\Exception $e) {
        error_log("GeneralExcpeption: " . $e->getTraceAsString());
        //no throw
    }
    

    您总是捕获从最具体(在您的案例中为 Doctrine)到不太具体(\Exception)的异常

    使用getTrace 可能比使用getTraceAsString() 更容易查看导致异常的执行顺序。 但请帮自己一个忙,并限制您显示的条目数量,即这样:

    try {
        // application init
        $app->init();
    
    //note backslash
    } catch (\Doctrine\Common\Persistence\Mapping\MappingException $e) {
    
        var_export(array_slice($e->getTrace(), 0, 5));
        //no throw
    
    } catch (\Exception $e) {
    
        var_export(array_slice($e->getTrace(), 0, 5));
        //no throw
    }
    

    如果数字 5 不够,则返回到您使用 Client 的位置,然后将其增加到 10、15 等,以便能够返回到异常发生之前执行的位置。每个条目都有文件和行号,因此您将能够重新创建发生的事情。

    查看您拥有Client 的代码,并检查您是否在您所在的命名空间中正确使用了该客户端。如果在您使用 Client 的 php 文件顶部有一个 namespace 关键字,您需要确保 Client 是该 namespace 的一部分或使用 \Client 转义命名空间并处理名称Client 好像没有命名空间一样。

    2。异常是在你的 try catch 块之外抛出的(可能不是)

    您可以通过在处理程序中注册自己的函数来尝试捕获 try/catch 块之外的异常。棘手的部分是这必须在 php 代码的第一行完美地抛出异常之前完成。请注意,这可能与您编写的第一行不同,例如这可以是应用程序 bootstrap.php。 您可以通过运行带有 Xdebug 的应用程序进入调试模式来检查您的应用程序的第一行是什么。

    这是放置异常处理程序的示例:

    <?php
    function exception_handler($e) {
      echo "MyUncaughtException: " , $e->getMessage(), "\n";
    }
    
    set_exception_handler('exception_handler');
    

    【讨论】:

    • 谢谢@Jimmix!从你的长评论 $e->getTrace() 帮助我分析堆栈跟踪并找到解决方案。
    • > 文件:/var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/MappingException.php 行:93
    • @AndreyLebedev 欢迎您,如果您的答案令您满意,请考虑将其标记为已接受,以便其他人看到您的问题已经回答。
    猜你喜欢
    • 2014-04-09
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多