9

Is there a way to force a batch process to stop if some kind of error occurs? In particular, I have a batch that starts with saving a record to a database. Each subsequent batch operation depends on the database insert working correctly. I'd like to force the batch to stop if the first batch fails.

The batch is called like this

$batch = array(
    'operations' => $operations,
    'finished' => 'mymodule_batch_finished',
    'title' => t('Merging records'),
    'init_message' => t('Starting processing'),
    'progress_message' => t('Processed @current out of @total.'),
    'error_message' => t('Processing has encountered an error'),
    'file' => drupal_get_path('module', 'mymodule') . '/forms/mymodule.inc'
);

where $operations is the array of functions to call.

Each function uses PDO to update the database. I'm trying to figure out how to stop the subsequent $operations from being called if the query in the current operation fails.

try {
  $sth = $dbh->prepare($sql);
  $sth->bindParam(':newid',$new_id,PDO::PARAM_INT);
  $sth->bindParam(':id',$id,PDO::PARAM_INT);
  if($sth->execute()) {
    $context['results']['[] = $sth->rowCount();
  }
  else {
    // TODO: stop processing due to an error
  }
}
catch(PDOException $e) {
  // TODO: stop processing due to an error
}

If an error occurs, I want to bypass the remaining operations and go straight to mymodule_batch_finished

2
  • How do you currently perform the saving into the database? What triggers the batch process?
    – Randell
    Mar 4, 2014 at 5:09
  • added details to answer your questions.
    – Robbert
    Mar 4, 2014 at 5:13

2 Answers 2

15
+50

Inside your batch callback, where you do the batch work, you should be able to set $context['finished'] to 1, and that will signal to Drupal that the batch is complete.

So, in your case:

$error = FALSE;
try {
  $sth = $dbh->prepare($sql);
  $sth->bindParam(':newid',$new_id,PDO::PARAM_INT);
  $sth->bindParam(':id',$id,PDO::PARAM_INT);
  if($sth->execute()) {
    $context['results'][] = $sth->rowCount();
  }
  else {
    $error = TRUE;
  }
}
catch (PDOException $e) {
  $error = TRUE;
}
// If there was an error, immediately complete the batch process.
if ($error) {
  $context['finished'] = 1;
}

And, even better, you can pass in an error message in the $context as well, which you can check for in your finished callback, then display to the end user in case of failure.

If you want to immediately stop processing anything in other callbacks in the $operations list, you might also need to check for a static variable at the beginning of each callback, and skip the callback if it's in an error condition. You could try using variable_get/variable_set, or some other mechanism that persists between page requests. This would definitely be a hackish/last-resort solution, though!

See also:

-1

Can you try below code ?

$result = array('status' => FALSE, 'data' => $message);
die(json_encode($result));
1
  • That'll just show me an error page. I want to bypass the remaining operations and go straight to mymodule_batch_finished
    – Robbert
    Mar 4, 2014 at 5:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.