rector icon indicating copy to clipboard operation
rector copied to clipboard

Display stack trace on `--debug` without wrapping it in `[ ERROR ]` block style

Open ruudk opened this issue 3 years ago • 2 comments

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.

ruudk avatar Aug 25 '22 09:08 ruudk

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.

ruudk avatar Aug 25 '22 09:08 ruudk

Sounds reasonable :)

I'd have to see the before after example. Could you send the PR with screens?

TomasVotruba avatar Aug 25 '22 10:08 TomasVotruba

Closing for lack of feedback, to keep issue tracker focus on unclear issues that needs our attention.

Thank you for understanding :slightly_smiling_face:

TomasVotruba avatar Oct 13 '22 01:10 TomasVotruba