There doesnt seem to be any way to end a batch operation stating an error. The $context['finished'] variable tracks the progress of the current batch operation. Once $context['finished'] is set to 1 (=100%) the operation ends. However I couldnt find a solution to interrupt the operation in case an error occurs. I tried $context['finished'] = -1 and searched the code for a error state variable, but there doesnt seem to be one. The only way to stop processing is to set $context['finished'] = 1, but this results in $success = TRUE in the _finished() handler. Is there something I missed here? How can I stop batch processing in case an error occurs during batch operation? Actually the batch_example module doesnt cover this case either. All current implementations neglect the state of errors during operation AFAICT.

<?php
function _mymodule_batch_operation(&$context) {
  if (empty($context['sandbox'])) {
    // Initialize batch variables
    $context['finished'] = 0;
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['max'] = _mymodule_count_items();
  }
  // Perform operation
  if (!_mymodule_do_something($context['results'])) {
    $context['finished'] = 1;
    return;
  }
  
  $context['sandbox']['progress'] += BATCH_INTERVAL;
  $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
?>

The snippet above contains a function _mymodule_do_something() that can fail (returns FALSE on failure). To end operation in that case I'm currently setting $context['finished'] = 1 and return. However even if I add something like drupal_set_message('...', 'error') before the return, batch API still displays success message because in the _finished() callback the $success variable is TRUE.

This is what I think should be possible ...

<?php
if (!_mymodule_do_something($context['results'])) {
  $context['finished'] = -1;
  return;
}
// - OR -
if (!_mymodule_do_something($context['results'])) {
  $context['finished'] = 1;
  $context['error'] = TRUE;
  return;
}
?>

I dont see any possible workaround at this point (please let me know if there is one), thats why I consider this a bug (critical even?). There is no way to cleanly handle errors and shutdown the batch operation safely ATM.

Comments

yched’s picture

True, this feature has not been included in the initial list for the batch engine.
There is no way an operation can stop the rest of the batch from being executed - however, you can use $context['results'] in any way you like to store errors and maybe put a flag for subsequent operations to do nothing...

Not sure we want to hardcode anything about that for D6 - quite convinced of the opposite, actually :-)

profix898’s picture

Thanks yched for the comment :) The batch API stuff in core is really cool, but very few people are using it atm. Some issues remained undiscovered for that reason, I guess. In my current dev implementation I use $context['results'] to store an error flag. The problem is that without hacking core files it is impossible to interrupt batch operations on error conditions.
For example: Say you have 2 operations executed subsequently in a batch process and #2 somehow depends on #1. Now if #1 fails for some reason, there is no way to skip #2 and it will always show the success message. Thats not only bad from a developer's perspective, but also from the usability point of view. Because (if you manually put a error message) we show two mutually exclusive messages to the users (one saying success, the other error) ...

yched’s picture

The $success variable in 'finished' callbacks might actually be a bit misleading : It is a 'low level' notion of error, which only indicates whether all the successive HTTP requests went smoothly or whether a critical PHP error occurred in one of the iterations.
Your processing can be "successfull" in that sense, while still having encountered errors according to its own standards (say, incorrect line in a CSV file being imported). Any other error management you have to implement yourself, using $context['results']
I'll try to see if the doc can be made clearer about that.

What if your operation 1 stores $context['results']['skip'] = TRUE; when it encounters its notion of 'error', and operation 2 starts with if (empty($context['results']['skip']) {... do the stuff ...} ? Wouldn't that do the trick ?

It's the way it's intended to work : $context['results'] is a storage area you can structure in any way that fits your needs to implement the workflow you need.

I _think_ the current state of the engine, while hardcoding very little, lets you have various workflow control / error management, depending on the specific needs of your batch processing.

profix898’s picture

Version: 6.x-dev » 7.x-dev
Category: bug » feature

Hmm. Then I think I should simply provide an _finished callback to suppress the semi-'success' message and code the 'high level'-error handling myself. Thanks for making this clear.

I will make this a feature request for D7. Maybe we can think of a simple error handling mechanism later.

Steven Jones’s picture

Version: 7.x-dev » 8.x-dev

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Alan D.’s picture

Version: 8.2.x-dev » 8.3.x-dev

Come across this looking for the best way to stop this myself in a multitask batch process.

It can be done easily in Drupal 7, using a sledgehammer approach, by throwing an Exception in the task.

Creating a custom BatchException could be a clean way to handle this cleanly with minimal work to capture this without the 500 error, currently you get this:

An AJAX HTTP error occurred. HTTP Result Code: 500 Debugging information follows. Path: /batch?id=18&op=do StatusText: Service unavailable (with message) ResponseText: Exception: ...

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.