PHP Quick Stack Trace in Exception Handler
PHP and frameworks built from it have many great tools to assist with debugging (I particularly like XDebug) but sometimes you can find yourself in a situation where the “helper” features aren’t all that much help … in my case this was a framework totally determined to output HTML from my commandline script and to only show me 5 lines of stack trace, which wasn’t enough for my complex application. I had to look up how to generate a nice stack trace inside an exception handler so here it is in case I want it again some time (future me, you’re welcome!)
set_exception_handler(function (Exception $e) { echo "EXCEPTION " . $e->getMessage() . "\n"; echo "originates: " . $e->getFile() . " (" . $e->getLine() . ")\n"; $backtrace = $e->getTrace(); foreach ($backtrace as $key => $row) { echo $row['file'] . " (" . $row['line'] . ")\n"; } exit; });
This is intended for me to be able to spot the output even in a raft of fairly chatty debug output (although it’s very restrained considering my usual **ASCII ART**
tendencies). The initial trigger of the exception is stored in the exception itself, and then “how did we get there?” is in the Exception::getTrace()
method, so this outputs the originating information and then works back up the stack to give context.
I thought I’d share in case it’s useful – strangely we must all be using code like this in places, but I wasn’t able to quickly grab an example when I wanted one.
I use something similar – just wanted to mention that some entries in the stack trace may not have file / line keys.
I ususally use $exception->getTraceAsString() which is super helpful.
The file and line properties are not always set (in the case of internal functions) so you should use isset.
Also it is helpful to output the class and function properties too.
Lastly I like to kill debug output with a die(__FILE__); so I know exactly where execution ended.
And why not use PHP_EOL instead of “\n”?
Pure laziness and a known platform. The constant would be more correct
While we are at it, why not add a error handler too?
set_error_handler(function($code, $message, $file, $line, $context) {
echo “Error $code occurred: $message” . PHP_EOL;
echo “On line $line of $file” . PHP_EOL;
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
die(“Execution killed in ” . __FILE__);
});
This was specifically my exception handler. I may share my error handler code in a separate post but thanks for sharing yours :)