Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ErrorException when catching errors while processing scheduled actions #1052

Open
james-allan opened this issue Apr 12, 2024 · 1 comment · May be fixed by #1057
Open

Use ErrorException when catching errors while processing scheduled actions #1052

james-allan opened this issue Apr 12, 2024 · 1 comment · May be fixed by #1057
Labels
type: enhancement The issue is a request for an enhancement.

Comments

@james-allan
Copy link
Contributor

james-allan commented Apr 12, 2024

Description

In the ActionScheduler_Abstract_QueueRunner::process_action() function AS sets an error handler and any E_USER_ERROR or E_RECOVERABLE_ERROR error that occurs while processing the action is caught and thrown as an exception instead.

This is super handy for Woo Subscriptions because AS will trigger the action_scheduler_failed_execution action which passes callbacks the exception that was caught.

Woo Subscriptions uses this hook to log data about why our subscription-related scheduled actions have failed, however something I noticed today is that because AS is creating a new exception, if you use the $exception->getFile() $exception->getLine() helpers to point to where the exception occured, it will point to AS, not where the error was actually thrown.

eg

$exception->getMessage() . ' in ' . $exception->getFile() . ':' . $exception->getLine()

Something like that above will result in the following:

 This is a fatal error in .../woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php:63 

If you use ErrorException instead and pass the file and line number params, callbacks attached to the action_scheduler_failed_execution can more accurately determine where the error is occurring.

To replicate

  1. Add the following code snippet to trigger an error and log the exception.
// Trigger a user error on action schedule execute.
add_action( 'action_scheduler_begin_execute', function() {
	trigger_error( 'Oops!', E_USER_ERROR );
} );

// Log the exception caught.
add_action( 'action_scheduler_failed_execution', function ( $action_id, $e, $context ) {
	$message = sprintf( 'Action failed: %s in %s: %d', $e->getMessage(), $e->getFile(), $e->getLine() );
	error_log( $message );
	ActionScheduler_Logger::instance()->log( $action_id, $message );
}, 10, 3 );
  1. Run any scheduled action.
  2. When the event runs, you should see the following in your debug log or on the scheduled action log.
  3. Note that the file and line number point to AS files.
Action failed: Oops! in /public/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php: 95

Using ErrorException and passing the additional file and line number args instead of an standard exception here, should do the trick.

@barryhughes
Copy link
Member

Thanks for suggesting this, @james-allan. It makes sense to me and actually we have a very similar existing report, but my sense of things is that what you've proposed here is probably the preferable course of action. I'll follow up later and we can close the other issue, unless there is any disagreement/reasons we've missed.

Marking as an enhancement and, of course, we'd be very receptive to a pull request for this (though no problem if you don't have time).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement The issue is a request for an enhancement.
Projects
None yet
2 participants