Display stack trace on `--debug` without wrapping it in `[ ERROR ]` block style
Feature Request
When developing Rector rules I often use --debug. Every now and then I get an exception because I make a mistake in my rule. That's expected.
But the exceptions are always presented in a very annoying truncated way that make it impossible to click the files as they are on multiple lines.
Example:
[ERROR] Could not process "src/Core/Api/Infrastructure/GraphQL/Types/MutationType.php"
file, due to:
"System error: "Call to a member function getAttribute() on null"
Stack trace:
#0
phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Nod
eScopeResolver.php(1605):
PHPStan\Reflection\ParametersAcceptorSelector::selectFromArgs(Object(PHPStan\Ana
lyser\MutatingScope), Array, Array)
#1
phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Nod
eScopeResolver.php(499):
PHPStan\Analyser\NodeScopeResolver->processExprNode(Object(PhpParser\Node\Expr</>
MethodCall), Object(PHPStan\Analyser\MutatingScope), Object(Closure),
Object(PHPStan\Analyser\ExpressionContext))
#2
phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Nod
eScopeResolver.php(326):
PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt</>
Return_), Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#3
phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Nod
eScopeResolver.php(484):
PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt
\ClassMethod), Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#4
phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Nod
eScopeResolver.php(326):
PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt</>
ClassMethod), Object(PHPStan\Analyser\MutatingScope),
Object(PHPStan\Node\ClassStatementsGatherer))
#5
phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Nod
eScopeResolver.php(562):
PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt
\Class_), Array, Object(PHPStan\Analyser\MutatingScope),
Object(PHPStan\Node\ClassStatementsGatherer))
#6
phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Nod
eScopeResolver.php(326):
PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt</>
Class_), Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#7
phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Nod
eScopeResolver.php(534):
PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt
\Namespace_), Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#8
phar://vendor/rector/rector/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Nod
eScopeResolver.php(296):
PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt</>
Namespace_), Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#9
vendor/rector/rector/packages/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeRes
olver.php(268): PHPStan\Analyser\NodeScopeResolver->processNodes(Array,
Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#10
vendor/rector/rector/packages/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeRes
olver.php(220):
Rector\NodeTypeResolver\PHPStan\Scope\PHPStanNodeScopeResolver->processNodesWit
hDependentFiles(Object(RectorPrefix202206\Symplify\SmartFileSystem\SmartFileInfo
), Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#11 vendor/rector/rector/src/Application/ChangedNodeScopeRefresher.php(121):
Rector\NodeTypeResolver\PHPStan\Scope\PHPStanNodeScopeResolver->processNodes(Ar
ray, Object(RectorPrefix202206\Symplify\SmartFileSystem\SmartFileInfo),
Object(PHPStan\Analyser\MutatingScope))
#12 vendor/rector/rector/src/Rector/AbstractRector.php(261):
Rector\Core\Application\ChangedNodeScopeRefresher->refresh(Object(PhpParser\Nod
e\Stmt\Namespace_), Object(PHPStan\Analyser\MutatingScope),
Object(RectorPrefix202206\Symplify\SmartFileSystem\SmartFileInfo))
#13
vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(176
):
Rector\Core\Rector\AbstractRector->enterNode(Object(PhpParser\Node\Stmt\Namespa
ce_))
#14
vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(85)
: PhpParser\NodeTraverser->traverseArray(Array)
#15
vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(42):
PhpParser\NodeTraverser->traverse(Array)
#16 vendor/rector/rector/src/Application/FileProcessor.php(61):
Rector\Core\PhpParser\NodeTraverser\RectorNodeTraverser->traverse(Array)
#17
vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(126):
Rector\Core\Application\FileProcessor->refactor(Object(Rector\Core\ValueObject</>
Application\File), Object(Rector\Core\ValueObject\Configuration))
#18 vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(93):
Rector\Core\Application\FileProcessor\PhpFileProcessor->refactorNodesWithRector
s(Object(Rector\Core\ValueObject\Application\File),
Object(Rector\Core\ValueObject\Configuration))
#19 vendor/rector/rector/packages/Parallel/WorkerRunner.php(99):
Rector\Core\Application\FileProcessor\PhpFileProcessor->process(Object(Rector\C
ore\ValueObject\Application\File),
Object(Rector\Core\ValueObject\Configuration))
#20
vendor/rector/rector/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.
php(97): Rector\Parallel\WorkerRunner->Rector\Parallel\{closure}(Array)
#21 vendor/rector/rector/vendor/clue/ndjson-react/src/Decoder.php(110):
RectorPrefix202206\Evenement\EventEmitter->emit('data', Array)
#22
vendor/rector/rector/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.
php(97): RectorPrefix202206\Clue\React\NDJson\Decoder->handleData(Array)
#23 vendor/rector/rector/vendor/react/stream/src/Util.php(62):
RectorPrefix202206\Evenement\EventEmitter->emit('data', Array)
#24
vendor/rector/rector/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.
php(97):
RectorPrefix202206\React\Stream\Util::RectorPrefix202206\React\Stream\{closure}(
'{"action":"main...')
#25 vendor/rector/rector/vendor/react/stream/src/DuplexResourceStream.php(154):
RectorPrefix202206\Evenement\EventEmitter->emit('data', Array)
#26 vendor/rector/rector/vendor/react/event-loop/src/StreamSelectLoop.php(201):
RectorPrefix202206\React\Stream\DuplexResourceStream->handleData(Resource id
#2998)
#27 vendor/rector/rector/vendor/react/event-loop/src/StreamSelectLoop.php(173):
RectorPrefix202206\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL
)
#28 vendor/rector/rector/src/Console/Command/WorkerCommand.php(63):
RectorPrefix202206\React\EventLoop\StreamSelectLoop->run()
#29 vendor/rector/rector/vendor/symfony/console/Command/Command.php(307):
Rector\Core\Console\Command\WorkerCommand->execute(Object(RectorPrefix202206\Sy
mfony\Component\Console\Input\ArgvInput),
Object(RectorPrefix202206\Symfony\Component\Console\Output\ConsoleOutput))
#30 vendor/rector/rector/vendor/symfony/console/Application.php(891):
RectorPrefix202206\Symfony\Component\Console\Command\Command->run(Object(Rector
Prefix202206\Symfony\Component\Console\Input\ArgvInput),
Object(RectorPrefix202206\Symfony\Component\Console\Output\ConsoleOutput))
#31 vendor/rector/rector/vendor/symfony/console/Application.php(310):
RectorPrefix202206\Symfony\Component\Console\Application->doRunCommand(Object(R
ector\Core\Console\Command\WorkerCommand),
Object(RectorPrefix202206\Symfony\Component\Console\Input\ArgvInput),
Object(RectorPrefix202206\Symfony\Component\Console\Output\ConsoleOutput))
#32 vendor/rector/rector/src/Console/ConsoleApplication.php(49):
RectorPrefix202206\Symfony\Component\Console\Application->doRun(Object(RectorPr
efix202206\Symfony\Component\Console\Input\ArgvInput),
Object(RectorPrefix202206\Symfony\Component\Console\Output\ConsoleOutput))
#33 vendor/rector/rector/vendor/symfony/console/Application.php(208):
Rector\Core\Console\ConsoleApplication->doRun(Object(RectorPrefix202206\Symfony
\Component\Console\Input\ArgvInput),
Object(RectorPrefix202206\Symfony\Component\Console\Output\ConsoleOutput))
#34 vendor/rector/rector/bin/rector.php(128):
RectorPrefix202206\Symfony\Component\Console\Application->run()
#35 vendor/rector/rector/bin/rector(5): require_once('/Volumes/CS/www...')
#36 vendor/bin/rector(120): include('/Volumes/CS/www...')
#37 {main}". On line: 58
I would suggest to print the exceptions/stack traces directly, without using $this->rectorOutputStyle->error($message); that causes the lines to be wrapped and prefixed with [ERROR].
https://github.com/rectorphp/rector-src/blob/7215c28735a3f1b3e56f86b5b57085ec3d8956c3/packages/ChangesReporting/Output/ConsoleOutputFormatter.php#L106-L126
If you agree, then I can create the pull request and flip this behaviour when --debug is used.
I feel this happens because I run it with PHPStorm Run Configuration. I suspect it sets COLUMNS to a low number and therefore causes the wrapping.
Sounds reasonable :)
I'd have to see the before after example. Could you send the PR with screens?
Closing for lack of feedback, to keep issue tracker focus on unclear issues that needs our attention.
Thank you for understanding :slightly_smiling_face: