Как найти место в коде, где были вызваны исключения Doctrine?

#php #debugging #exception #doctrine-orm #doctrine

#php #отладка #исключение #doctrine-orm #doctrine

Вопрос:

Где-то в моем коде было MappingException. Пожалуйста, помогите мне, как найти место в коде, где возникает это исключение?

 [29-Mar-2019 22:30:26 Europe/Moscow] PHP Fatal error:  Uncaught DoctrineCommonPersistenceMappingMappingException: 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): DoctrineCommonPersistenceMappingMappingException::nonExistingClass('Client')
#1 /var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(251): DoctrineCommonPersistenceMappingRuntimeReflectionService->getParentClasses('Client')
#2 /var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(284): DoctrineCommonPersistenceMappingAbstractClassMetadataFactory->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 (DoctrineCommonPersistenceMappingMappingException $e) {
    error_log("MappingException: " . $e->getTraceAsString());
    throw $e;
}
  

Обновить

Проблема была связана не с Doctrine в точности, а с длиной трассировки стека, которая слишком велика и не умещается в 1024 байта (настройка php по умолчанию). Итак, просто нужно увеличить максимальную длину трассировки стека, что можно сделать с помощью команды follow:

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

Комментарии:

1. Я не работал с doctrine. Но похоже на неудачную инъекцию зависимости. Ожидает ли какой-либо из ваших классов зависимости от клиентского класса?

2. Да, похоже, проблема с внедрением зависимостей, я проверил все свои объекты, репозитории и все остальное и ничего не нашел. Я думаю, что современный инструмент ORM должен предоставлять подробный отчет об ошибке, который включает место в коде, где возникло исключение.

Ответ №1:

Исключение было сгенерировано в:

файл: /var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/MappingException.php

строка: 93

Если вы хотите увидеть, что произошло раньше (причину), вы можете проверить трассировку вашего кода. Я не вижу весь ваш код, но:

Если у вас есть неперехваченное исключение, даже если вы обернули свой код с помощью блока 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 (DoctrineCommonPersistenceMappingMappingException $e) {
    error_log("MappingException: " . $e->getTraceAsString());
    //no throw

} catch (Exception $e) {
    error_log("GeneralExcpeption: " . $e->getTraceAsString());
    //no throw
}
  

Вы всегда перехватываете исключения, начиная с наиболее специфичных (Doctrine в вашем случае) и заканчивая менее специфичными ( Exception)

Вероятно, будет намного проще работать с getTrace, чем с getTraceAsString(), чтобы увидеть порядок выполнения, который привел к исключению. но сделайте себе одолжение и ограничьте количество записей, которые вы отображаете, ie таким образом:

 try {
    // application init
    $app->init();

//note backslash
} catch (DoctrineCommonPersistenceMappingMappingException $e) {

    var_export(array_slice($e->getTrace(), 0, 5));
    //no throw

} catch (Exception $e) {

    var_export(array_slice($e->getTrace(), 0, 5));
    //no throw
}
  

и вернитесь назад к месту, где вы использовали Client если числа 5 недостаточно, увеличьте его до 10, 15 и т.д., Чтобы иметь возможность вернуться назад, где выполнение было до возникновения исключения. Каждая запись имеет номер файла и строки, так что вы сможете воссоздать то, что произошло.

Посмотрите на свой код, где у вас есть ваш Client и убедитесь, что вы правильно использовали этот клиент в пространстве имен, в котором вы находитесь. Если в верхней части файла php, в котором вы используете, есть namespace ключевое слово, которое вы используете Client , вам нужно быть уверенным, что оно Client является его частью namespace , или использовать Client для выхода из пространства имен и обрабатывать имя Client так, как если бы пространства имен не было.

2. Исключение выдается за пределами вашего блока try catch (вероятно, нет)

Вы можете попытаться перехватить исключения, которые находятся за пределами вашего блока try / catch, зарегистрировав свою собственную функцию с помощью handler. Сложность заключается в том, что это должно быть сделано до того, как исключение будет выдано так идеально в первой строке php-кода. Обратите внимание, что это может отличаться от первой строки, которую вы написали, например, это может быть application bootstrap.php . вы можете проверить, какова первая строка вашего приложения, запустив приложение с помощью Xdebug в режиме отладки.

вот пример установки обработчика исключения:

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

set_exception_handler('exception_handler');
  

Комментарии:

1. Спасибо @Jimmix! Ваш длинный комментарий $ e-> getTrace() помог мне проанализировать трассировку стека и нашел решение.

2. > файл: /var/www/virtual/account/htdocs/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/MappingException.php строка: 93

3. @AndreyLebedev Добро пожаловать, если ответ вас удовлетворил, пожалуйста, подумайте о том, чтобы пометить его как принятый, чтобы ваш вопрос отображался для других как уже отвеченный.

Ответ №2:

Проблема была связана не с Doctrine в точности, а с длиной трассировки стека, которая слишком велика и не умещается в 1024 байта (настройка php по умолчанию). Итак, просто нужно увеличить максимальную длину трассировки стека, что можно сделать с помощью команды follow:

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