@@ -89,6 +89,7 @@ class ErrorHandler
89
89
private $ tracedErrors = 0x77FB ; // E_ALL - E_STRICT - E_PARSE
90
90
private $ screamedErrors = 0x55 ; // E_ERROR + E_CORE_ERROR + E_COMPILE_ERROR + E_PARSE
91
91
private $ loggedErrors = 0 ;
92
+ private $ traceReflector ;
92
93
93
94
private $ isRecursive = 0 ;
94
95
private $ isRoot = false ;
@@ -147,6 +148,8 @@ public function __construct(BufferingLogger $bootstrappingLogger = null)
147
148
$ this ->bootstrappingLogger = $ bootstrappingLogger ;
148
149
$ this ->setDefaultLogger ($ bootstrappingLogger );
149
150
}
151
+ $ this ->traceReflector = new \ReflectionProperty ('Exception ' , 'trace ' );
152
+ $ this ->traceReflector ->setAccessible (true );
150
153
}
151
154
152
155
/**
@@ -389,16 +392,37 @@ public function handleError($type, $message, $file, $line, array $context, array
389
392
self ::$ toStringException = null ;
390
393
} elseif (!$ throw && !($ type & $ level )) {
391
394
$ errorAsException = new SilencedErrorContext ($ type , $ file , $ line );
392
- } elseif ($ this ->scopedErrors & $ type ) {
393
- $ errorAsException = new ContextErrorException ($ logMessage , 0 , $ type , $ file , $ line , $ context );
394
395
} else {
395
- $ errorAsException = new \ErrorException ($ logMessage , 0 , $ type , $ file , $ line );
396
+ if ($ this ->scopedErrors & $ type ) {
397
+ $ errorAsException = new ContextErrorException ($ logMessage , 0 , $ type , $ file , $ line , $ context );
398
+ } else {
399
+ $ errorAsException = new \ErrorException ($ logMessage , 0 , $ type , $ file , $ line );
400
+ }
401
+
402
+ // Clean the trace by removing function arguments and the first frames added by the error handler itself.
403
+ if ($ throw || $ this ->tracedErrors & $ type ) {
404
+ $ backtrace = $ backtrace ?: $ errorAsException ->getTrace ();
405
+ $ lightTrace = $ backtrace ;
406
+
407
+ for ($ i = 0 ; isset ($ backtrace [$ i ]); ++$ i ) {
408
+ if (isset ($ backtrace [$ i ]['file ' ], $ backtrace [$ i ]['line ' ]) && $ backtrace [$ i ]['line ' ] === $ line && $ backtrace [$ i ]['file ' ] === $ file ) {
409
+ $ lightTrace = array_slice ($ lightTrace , 1 + $ i );
410
+ break ;
411
+ }
412
+ }
413
+ if (!($ throw || $ this ->scopedErrors & $ type )) {
414
+ for ($ i = 0 ; isset ($ lightTrace [$ i ]); ++$ i ) {
415
+ unset($ lightTrace [$ i ]['args ' ]);
416
+ }
417
+ }
418
+ $ this ->traceReflector ->setValue ($ errorAsException , $ lightTrace );
419
+ } else {
420
+ $ this ->traceReflector ->setValue ($ errorAsException , array ());
421
+ }
396
422
}
397
423
398
424
if ($ throw ) {
399
425
if (E_USER_ERROR & $ type ) {
400
- $ backtrace = $ backtrace ?: $ errorAsException ->getTrace ();
401
-
402
426
for ($ i = 1 ; isset ($ backtrace [$ i ]); ++$ i ) {
403
427
if (isset ($ backtrace [$ i ]['function ' ], $ backtrace [$ i ]['type ' ], $ backtrace [$ i - 1 ]['function ' ])
404
428
&& '__toString ' === $ backtrace [$ i ]['function ' ]
@@ -440,14 +464,6 @@ public function handleError($type, $message, $file, $line, array $context, array
440
464
throw $ errorAsException ;
441
465
}
442
466
443
- if (!($ this ->tracedErrors & $ type ) && $ errorAsException instanceof \Exception) {
444
- static $ freeTrace = null ;
445
- if (null === $ freeTrace ) {
446
- $ freeTrace = \Closure::bind (function ($ e ) { $ e ->trace = array (); }, null , \Exception::class);
447
- }
448
- $ freeTrace ($ errorAsException );
449
- }
450
-
451
467
if ($ this ->isRecursive ) {
452
468
$ log = 0 ;
453
469
} elseif (self ::$ stackedErrorLevels ) {
0 commit comments