#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