[GH-ISSUE #693] Fatal errors have no backtrace, IntrospectionProcessor can be smarter #255

Closed
opened 2026-03-04 02:13:31 +03:00 by kerem · 5 comments
Owner

Originally created by @razvanphp on GitHub (Nov 30, 2015).
Original GitHub issue: https://github.com/Seldaek/monolog/issues/693

I can provide more info on this, but according to our debugging, when a fatal error occurs, the line, function and co are in the context not in the extra, so IntrospectionProcessor does nothing, and puts null in all fields.

I think one of them should be smarter. I can prepare a PR if needed.

Originally created by @razvanphp on GitHub (Nov 30, 2015). Original GitHub issue: https://github.com/Seldaek/monolog/issues/693 I can provide more info on this, but according to our debugging, when a fatal error occurs, the line, function and co are in the `context` not in the `extra`, so `IntrospectionProcessor` does nothing, and puts null in all fields. I think one of them should be smarter. I can prepare a PR if needed.
kerem 2026-03-04 02:13:31 +03:00
  • closed this issue
  • added the
    Feature
    label
Author
Owner

@patrick-mcdougle commented on GitHub (Jan 26, 2016):

👍 The fatal error handler passes in all the data (message, type, line no) from the exception except for the trace, I think it should just pass the exception itself in and let the formatters decide what should be included from the exception object. For example, the line formatter could decide if it should include the trace or not.

Edit: I've misunderstood how this works. error_get_last() doesn't return an exception, it returns an array. This makes it hard/impossible to get a trace.

<!-- gh-comment-id:175202823 --> @patrick-mcdougle commented on GitHub (Jan 26, 2016): :+1: The fatal error handler passes in all the data (message, type, line no) from the exception except for the trace, I think it should just pass the exception itself in and let the formatters decide what should be included from the exception object. For example, the line formatter could decide if it should include the trace or not. Edit: I've misunderstood how this works. `error_get_last()` doesn't return an exception, it returns an array. This makes it hard/impossible to get a trace.
Author
Owner

@Seldaek commented on GitHub (Mar 1, 2016):

I think this can be fixed in 2.0 as php7 throws exceptions for fatal errors. But in 1.0 I don't see how we can fix anything if it really doesn't work right now.

<!-- gh-comment-id:190769011 --> @Seldaek commented on GitHub (Mar 1, 2016): I think this can be fixed in 2.0 as php7 throws exceptions for fatal errors. But in 1.0 I don't see how we can fix anything if it really doesn't work right now.
Author
Owner

@Seldaek commented on GitHub (May 26, 2016):

Closing as 2.0 now should handle fatals as exceptions, at least most. For the others like out of memory error I am not sure what we can do to be honest. If you find that it's still lacking and find a way to improve it please send a PR :)

<!-- gh-comment-id:221941597 --> @Seldaek commented on GitHub (May 26, 2016): Closing as 2.0 now should handle fatals as exceptions, at least most. For the others like out of memory error I am not sure what we can do to be honest. If you find that it's still lacking and find a way to improve it please send a PR :)
Author
Owner

@tractorcow commented on GitHub (Nov 15, 2017):

@Seldaek sorry to open an old issue, but in SilverStripe 3.x (before we moved to monolog) we would capture the stacktrace with debug_backtrace() in our error handlers.

github.com/silverstripe/silverstripe-framework@abe0e96192/dev/Debug.php (L572-L575)

Now that we are using monolog I would love to be able to restore this ability.

Although you cannot capture this from error_get_last(), you can create a separate registrar on ErrorHandler for the last stacktrace from this error. We could assign this in ErrorHandler::handleError, and ErrorHandler::handleFatalError could inspect this, passing it into the logger. :)

Pseudocode follows (because I'm lazy)

handleError() {
	$trace = debug_backtrace();
	if (!$fatal) {
		$logger->log($lastError, array('code' => $lastError['code'], 'trace' => $trace));
	} else {
		$this->fatalErrorTrace = $trace;
	}	
}
handleFatalError() {
	$lastError = error_get_last();
	if ($fatal) {
		$lastTrace = $this->fatalErrorTrace;
		$logger->log($lastError, array('code' => $lastError['code'], 'trace' => $lastTrace));
	}
}

If you think this is an appropriate approach is it worth my submitting a pull request as a proof of concept?

<!-- gh-comment-id:344483043 --> @tractorcow commented on GitHub (Nov 15, 2017): @Seldaek sorry to open an old issue, but in SilverStripe 3.x (before we moved to monolog) we would capture the stacktrace with `debug_backtrace()` in our error handlers. https://github.com/silverstripe/silverstripe-framework/blob/abe0e961927880021d59a8f0bdd475dbfe0f7570/dev/Debug.php#L572-L575 Now that we are using monolog I would love to be able to restore this ability. Although you cannot capture this from error_get_last(), you can create a separate registrar on ErrorHandler for the last stacktrace from this error. We could assign this in `ErrorHandler::handleError`, and `ErrorHandler::handleFatalError` could inspect this, passing it into the logger. :) Pseudocode follows (because I'm lazy) ```php handleError() { $trace = debug_backtrace(); if (!$fatal) { $logger->log($lastError, array('code' => $lastError['code'], 'trace' => $trace)); } else { $this->fatalErrorTrace = $trace; } } handleFatalError() { $lastError = error_get_last(); if ($fatal) { $lastTrace = $this->fatalErrorTrace; $logger->log($lastError, array('code' => $lastError['code'], 'trace' => $lastTrace)); } } ``` If you think this is an appropriate approach is it worth my submitting a pull request as a proof of concept?
Author
Owner

@tractorcow commented on GitHub (Nov 15, 2017):

Given the work required was no larger than my "lazy" pseudocode I've gone ahead and done so anyway. :)

https://github.com/Seldaek/monolog/pull/1080

Please let me know if I am going in the right direction.

<!-- gh-comment-id:344487338 --> @tractorcow commented on GitHub (Nov 15, 2017): Given the work required was no larger than my "lazy" pseudocode I've gone ahead and done so anyway. :) https://github.com/Seldaek/monolog/pull/1080 Please let me know if I am going in the right direction.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/monolog#255
No description provided.