diff options
author | Florian Pritz <bluewind@xinu.at> | 2015-01-03 17:21:35 +0100 |
---|---|---|
committer | Florian Pritz <bluewind@xinu.at> | 2015-01-03 17:41:10 +0100 |
commit | 6fb7f2bb97b18a7e3bd066d0d83bca1b1b81d2a0 (patch) | |
tree | 45abf630b7c1b179443944291e7aedd119c61737 | |
parent | 38db82116dfd543a08a553ae75112e6992a7718d (diff) |
Improve stacktrace generation (circular reference errors)
var_export can't handle circular references which can happen in
codeigniter's objects and if those get passed as arguments it will
throw another fatal error and the actual trace will get lost.
Signed-off-by: Florian Pritz <bluewind@xinu.at>
-rw-r--r-- | index.php | 48 |
1 files changed, 39 insertions, 9 deletions
@@ -211,6 +211,44 @@ function _exception_handler($errno, $errstr, $errfile, $errline) } set_error_handler("_exception_handler"); +// Source: https://gist.github.com/abtris/1437966 +function getExceptionTraceAsString($exception) { + $rtn = ""; + $count = 0; + foreach ($exception->getTrace() as $frame) { + $args = ""; + if (isset($frame['args'])) { + $args = array(); + foreach ($frame['args'] as $arg) { + if (is_string($arg)) { + $args[] = "'" . $arg . "'"; + } elseif (is_array($arg)) { + $args[] = "Array"; + } elseif (is_null($arg)) { + $args[] = 'NULL'; + } elseif (is_bool($arg)) { + $args[] = ($arg) ? "true" : "false"; + } elseif (is_object($arg)) { + $args[] = get_class($arg); + } elseif (is_resource($arg)) { + $args[] = get_resource_type($arg); + } else { + $args[] = $arg; + } + } + $args = join(", ", $args); + } + $rtn .= sprintf( "#%s %s(%s): %s(%s)\n", + $count, + isset($frame['file']) ? $frame['file'] : 'unknown file', + isset($frame['line']) ? $frame['line'] : 'unknown line', + (isset($frame['class'])) ? $frame['class'].$frame['type'].$frame['function'] : $frame['function'], + $args ); + $count++; + } + return $rtn; +} + // The actual exception handler function _actual_exception_handler($e) { @@ -220,15 +258,7 @@ function _actual_exception_handler($e) $heading = "Internal Server Error"; $message = "<p>An unhandled error occured.</p>\n"; - $backtrace = ""; - $i = 0; - foreach ($e->getTrace() as $key => $frame) { - $backtrace .= sprintf("#%d %s(%d): %s(%s)\n", - $i++, isset($frame["file"]) ? $frame["file"] : "[internal function]", - isset($frame["line"]) ? $frame["line"] : "", $frame["function"], implode(", ", array_map( - function ($e) { return var_export($e, true); }, $frame["args"]))); - } - + $backtrace = getExceptionTraceAsString($e); if ($display_errors) { $message .= '<div>'; $message .= '<b>Fatal error</b>: Uncaught exception '.get_class($e).'<br>'; |