Подтвердить что ты не робот

Как отобразить трассировку Exception в команде laravel console?

Я использую Laravel 5.1 для создания консольного приложения. Во время разработки я хотел бы отобразить трассировку исключения при возникновении ошибки. Однако, даже если я использую опцию -v -vv или -vvv в php artisan, я не получаю трассировку исключения для моих пользовательских команд. Я установил APP_DEBUG=true в мой .env, все еще не отслеживая трассировку исключений.

Вывод php artisan some:unknowncommand:

[InvalidArgumentException]                              
There are no commands defined in the "some" namespace.

Вывод php artisan -v some:unknowncommand:

[InvalidArgumentException]                              
  There are no commands defined in the "some" namespace.  

Exception trace:
 () at /Users/dirkpostma/Dropbox/Domains/dpepp/vendor/symfony/console/Application.php:501
 Symfony\Component\Console\Application->findNamespace() at /Users/dirkpostma/Dropbox/Domains/dpepp/vendor/symfony/console/Application.php:535
 Symfony\Component\Console\Application->find() at /Users/dirkpostma/Dropbox/Domains/dpepp/vendor/symfony/console/Application.php:192
 Symfony\Component\Console\Application->doRun() at /Users/dirkpostma/Dropbox/Domains/dpepp/vendor/symfony/console/Application.php:126
...

Теперь я создал очень простую консольную команду под названием dp: test со следующей функцией дескриптора:

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    generate error here
}

Вывод php artisan dp:test:

[Symfony\Component\Debug\Exception\FatalErrorException]
syntax error, unexpected 'error' (T_STRING)    

Вывод php artisan -v dp:test одинаков. Вывод php artisan -vvv dp:test одинаков.

В файле журнала DOES показана трассировка исключения, поэтому каким-то образом ее можно отобразить в cli. Я даже не вижу имя файла и linenumer, где возникает ошибка... Как я могу позаботиться об этом?

Спасибо заранее!

EDIT:

Копается немного дальше. Если я использую это в своей команде:

public function handle()
{
    throw new \Exception("test exception");
}

и я выдаю команду php artisan -v dp:test, печатается ошибка. Трассировка только не печатается, когда исключение выбрасывается из-за ошибки PHP. В методе Illuminate/Foundation/Bootstrap/HandleExceptions.php bootstrap Ошибки PHP преобразуются в Исключения. Когда это происходит, генерируется исключение, но при печати значение -v каким-то образом игнорируется. Это очень неудобно, потому что он сильно затрудняет отладку приложений CLI.

Я думаю, что решение можно найти в vendor/symfony/console/Application.php, method renderException.

Я собираюсь копать дальше позже, если кто-то другой не сможет указать решение быстрее меня: -)

4b9b3361

Ответ 1

Я нашел причину, по которой -v игнорируется:

в Illuminate/Foundation/Bootstrap/HandleExceptions.php, метод renderForConsole создает объект ConsoleOutput с настройками по умолчанию, не принимая во внимание параметры подробностей, заданные пользователем:

protected function renderForConsole($e)
{
    $this->getExceptionHandler()->renderForConsole(new ConsoleOutput, $e);
}

По этой причине любое значение -v -vv или -vvv установлено, $output->getVerbosity() in vendor/symfony/console/Application.php всегда меньше, чем OutputInterface::VERBOSITY_VERBOSE, поэтому трассировка стека не печатается.

Вероятно, я начинаю проблему с github, потому что я думаю, что это намного удобнее, если ошибки отображаются в CLI, если пользователь устанавливает -v.

Ответ 2

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

use Symfony\Component\Console\Output\OutputInterface;

И затем добавив это в начало вашей функции дескриптора:

$this->output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);

См. документацию для консоли symfony здесь http://symfony.com/doc/current/console/verbosity.html для получения дополнительной информации.

Ответ 3

Если вы посмотрите на класс Illuminate\Console\Command, вы увидите определение функции, которая записывает строку ошибки в консоль:

/**
 * Write a string as error output.
 *
 * @param  string  $string
 * @return void
 */
public function error($string)
{
    $this->output->writeln("<error>$string</error>");
}

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

/**
 * Write a string as error output.
 *
 * @param  string  $string
 * @return void
 */
public function error($string)
{
    $this->output->writeln("<error>$string</error>");
    $trace = debug_backtrace();
    foreach ($trace as $t) 
    {
        $this->output->writeln("Trace : " . $t['file'] . " on line " . $t['line'] . " function " . $t['function']);
    }

}