@@ -132,9 +132,9 @@ public function run(InputInterface $input = null, OutputInterface $output = null
132
132
$ e = class_exists (ErrorException::class) ? new ErrorException ($ e ) : (class_exists (LegacyFatalThrowableError::class) ? new LegacyFatalThrowableError ($ e ) : new \ErrorException ($ e ->getMessage (), $ e ->getCode (), E_ERROR , $ e ->getFile (), $ e ->getLine ()));
133
133
}
134
134
if ($ output instanceof ConsoleOutputInterface) {
135
- $ this ->renderException ($ e , $ output ->getErrorOutput ());
135
+ $ this ->renderThrowable ($ e , $ output ->getErrorOutput ());
136
136
} else {
137
- $ this ->renderException ($ e , $ output );
137
+ $ this ->renderThrowable ($ e , $ output );
138
138
}
139
139
};
140
140
if ($ phpHandler = set_exception_handler ($ renderException )) {
@@ -792,9 +792,13 @@ public static function getAbbreviations($names)
792
792
793
793
/**
794
794
* Renders a caught exception.
795
+ *
796
+ * @deprecated since Symfony 4.4, use "renderThrowable()" instead
795
797
*/
796
798
public function renderException (\Exception $ e , OutputInterface $ output )
797
799
{
800
+ @trigger_error (sprintf ('The "%s::renderException()" method is deprecated since Symfony 4.4, use "renderThrowable()" instead. ' , __CLASS__ ));
801
+
798
802
$ output ->writeln ('' , OutputInterface::VERBOSITY_QUIET );
799
803
800
804
$ this ->doRenderException ($ e , $ output );
@@ -805,8 +809,124 @@ public function renderException(\Exception $e, OutputInterface $output)
805
809
}
806
810
}
807
811
812
+ public function renderThrowable (\Throwable $ e , OutputInterface $ output ): void
813
+ {
814
+ if (__CLASS__ !== \get_class ($ this ) && __CLASS__ !== (new \ReflectionMethod ($ this , 'renderException ' ))->getDeclaringClass ()->getName ()) {
815
+ @trigger_error (sprintf ('The "%s::renderException()" method is deprecated since Symfony 4.4, use "renderThrowable()" instead. ' , __CLASS__ ));
816
+
817
+ if (!$ e instanceof \Exception) {
818
+ $ e = new ErrorException ($ e );
819
+ }
820
+
821
+ $ this ->renderException ($ e , $ output );
822
+
823
+ return ;
824
+ }
825
+
826
+ $ output ->writeln ('' , OutputInterface::VERBOSITY_QUIET );
827
+
828
+ $ this ->doRenderThrowable ($ e , $ output );
829
+
830
+ if (null !== $ this ->runningCommand ) {
831
+ $ output ->writeln (sprintf ('<info>%s</info> ' , sprintf ($ this ->runningCommand ->getSynopsis (), $ this ->getName ())), OutputInterface::VERBOSITY_QUIET );
832
+ $ output ->writeln ('' , OutputInterface::VERBOSITY_QUIET );
833
+ }
834
+ }
835
+
836
+ /**
837
+ * @deprecated since Symfony 4.4, use "doRenderThrowable()" instead
838
+ */
808
839
protected function doRenderException (\Exception $ e , OutputInterface $ output )
809
840
{
841
+ @trigger_error (sprintf ('The "%s::doRenderException()" method is deprecated since Symfony 4.4, use "doRenderThrowable()" instead. ' , __CLASS__ ));
842
+
843
+ do {
844
+ $ message = trim ($ e ->getMessage ());
845
+ if ('' === $ message || OutputInterface::VERBOSITY_VERBOSE <= $ output ->getVerbosity ()) {
846
+ $ class = \get_class ($ e );
847
+ $ class = 'c ' === $ class [0 ] && 0 === strpos ($ class , "class@anonymous \0" ) ? get_parent_class ($ class ).'@anonymous ' : $ class ;
848
+ $ title = sprintf (' [%s%s] ' , $ class , 0 !== ($ code = $ e ->getCode ()) ? ' ( ' .$ code .') ' : '' );
849
+ $ len = Helper::strlen ($ title );
850
+ } else {
851
+ $ len = 0 ;
852
+ }
853
+
854
+ if (false !== strpos ($ message , "class@anonymous \0" )) {
855
+ $ message = preg_replace_callback ('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/ ' , function ($ m ) {
856
+ return class_exists ($ m [0 ], false ) ? get_parent_class ($ m [0 ]).'@anonymous ' : $ m [0 ];
857
+ }, $ message );
858
+ }
859
+
860
+ $ width = $ this ->terminal ->getWidth () ? $ this ->terminal ->getWidth () - 1 : PHP_INT_MAX ;
861
+ $ lines = [];
862
+ foreach ('' !== $ message ? preg_split ('/\r?\n/ ' , $ message ) : [] as $ line ) {
863
+ foreach ($ this ->splitStringByWidth ($ line , $ width - 4 ) as $ line ) {
864
+ // pre-format lines to get the right string length
865
+ $ lineLength = Helper::strlen ($ line ) + 4 ;
866
+ $ lines [] = [$ line , $ lineLength ];
867
+
868
+ $ len = max ($ lineLength , $ len );
869
+ }
870
+ }
871
+
872
+ $ messages = [];
873
+ if (!$ e instanceof ExceptionInterface || OutputInterface::VERBOSITY_VERBOSE <= $ output ->getVerbosity ()) {
874
+ $ messages [] = sprintf ('<comment>%s</comment> ' , OutputFormatter::escape (sprintf ('In %s line %s: ' , basename ($ e ->getFile ()) ?: 'n/a ' , $ e ->getLine () ?: 'n/a ' )));
875
+ }
876
+ $ messages [] = $ emptyLine = sprintf ('<error>%s</error> ' , str_repeat (' ' , $ len ));
877
+ if ('' === $ message || OutputInterface::VERBOSITY_VERBOSE <= $ output ->getVerbosity ()) {
878
+ $ messages [] = sprintf ('<error>%s%s</error> ' , $ title , str_repeat (' ' , max (0 , $ len - Helper::strlen ($ title ))));
879
+ }
880
+ foreach ($ lines as $ line ) {
881
+ $ messages [] = sprintf ('<error> %s %s</error> ' , OutputFormatter::escape ($ line [0 ]), str_repeat (' ' , $ len - $ line [1 ]));
882
+ }
883
+ $ messages [] = $ emptyLine ;
884
+ $ messages [] = '' ;
885
+
886
+ $ output ->writeln ($ messages , OutputInterface::VERBOSITY_QUIET );
887
+
888
+ if (OutputInterface::VERBOSITY_VERBOSE <= $ output ->getVerbosity ()) {
889
+ $ output ->writeln ('<comment>Exception trace:</comment> ' , OutputInterface::VERBOSITY_QUIET );
890
+
891
+ // exception related properties
892
+ $ trace = $ e ->getTrace ();
893
+
894
+ array_unshift ($ trace , [
895
+ 'function ' => '' ,
896
+ 'file ' => $ e ->getFile () ?: 'n/a ' ,
897
+ 'line ' => $ e ->getLine () ?: 'n/a ' ,
898
+ 'args ' => [],
899
+ ]);
900
+
901
+ for ($ i = 0 , $ count = \count ($ trace ); $ i < $ count ; ++$ i ) {
902
+ $ class = isset ($ trace [$ i ]['class ' ]) ? $ trace [$ i ]['class ' ] : '' ;
903
+ $ type = isset ($ trace [$ i ]['type ' ]) ? $ trace [$ i ]['type ' ] : '' ;
904
+ $ function = isset ($ trace [$ i ]['function ' ]) ? $ trace [$ i ]['function ' ] : '' ;
905
+ $ file = isset ($ trace [$ i ]['file ' ]) ? $ trace [$ i ]['file ' ] : 'n/a ' ;
906
+ $ line = isset ($ trace [$ i ]['line ' ]) ? $ trace [$ i ]['line ' ] : 'n/a ' ;
907
+
908
+ $ output ->writeln (sprintf (' %s%s at <info>%s:%s</info> ' , $ class , $ function ? $ type .$ function .'() ' : '' , $ file , $ line ), OutputInterface::VERBOSITY_QUIET );
909
+ }
910
+
911
+ $ output ->writeln ('' , OutputInterface::VERBOSITY_QUIET );
912
+ }
913
+ } while ($ e = $ e ->getPrevious ());
914
+ }
915
+
916
+ protected function doRenderThrowable (\Throwable $ e , OutputInterface $ output ): void
917
+ {
918
+ if (__CLASS__ !== \get_class ($ this ) && __CLASS__ !== (new \ReflectionMethod ($ this , 'doRenderException ' ))->getDeclaringClass ()->getName ()) {
919
+ @trigger_error (sprintf ('The "%s::doRenderException()" method is deprecated since Symfony 4.4, use "doRenderThrowable()" instead. ' , __CLASS__ ));
920
+
921
+ if (!$ e instanceof \Exception) {
922
+ $ e = new ErrorException ($ e );
923
+ }
924
+
925
+ $ this ->doRenderException ($ e , $ output );
926
+
927
+ return ;
928
+ }
929
+
810
930
do {
811
931
$ message = trim ($ e ->getMessage ());
812
932
if ('' === $ message || OutputInterface::VERBOSITY_VERBOSE <= $ output ->getVerbosity ()) {
0 commit comments