summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rothstein <drothstein@gmail.com>2014-05-05 17:10:24 -0400
committerDavid Rothstein <drothstein@gmail.com>2014-05-05 17:10:24 -0400
commit07a910ede989af178d98c92aff7080bc027a06ce (patch)
tree980bd90370f2ba1d32e5dc1a5d569b3c3aa517ec
parent808a61aef282f43f55bf9d8db1de8d947f32e357 (diff)
downloadbrdo-07a910ede989af178d98c92aff7080bc027a06ce.tar.gz
brdo-07a910ede989af178d98c92aff7080bc027a06ce.tar.bz2
Issue #2021933 by Crell, David_Rothstein, joachim, lz1irq: Catch exceptions from queue workers.
-rw-r--r--CHANGELOG.txt2
-rw-r--r--includes/common.inc11
-rw-r--r--modules/system/system.test38
-rw-r--r--modules/system/tests/cron_queue_test.info6
-rw-r--r--modules/system/tests/cron_queue_test.module15
5 files changed, 70 insertions, 2 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 0a290b1c2..c4a1e5f58 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,8 @@
Drupal 7.28, xxxx-xx-xx (development version)
-----------------------
+- Made the cron queue system log any exceptions that are thrown while an item
+ in the queue is being processed, rather than stopping the entire PHP request.
- Improved screen reader support by adding an aria-live HTML attribute to file
upload fields when there is an error uploading the file (minor markup
change).
diff --git a/includes/common.inc b/includes/common.inc
index a443158f1..1c55f347c 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -5294,8 +5294,15 @@ function drupal_cron_run() {
$end = time() + (isset($info['time']) ? $info['time'] : 15);
$queue = DrupalQueue::get($queue_name);
while (time() < $end && ($item = $queue->claimItem())) {
- $function($item->data);
- $queue->deleteItem($item);
+ try {
+ $function($item->data);
+ $queue->deleteItem($item);
+ }
+ catch (Exception $e) {
+ // In case of exception log it and leave the item in the queue
+ // to be processed again later.
+ watchdog_exception('cron', $e);
+ }
}
}
// Restore the user.
diff --git a/modules/system/system.test b/modules/system/system.test
index f4fb047d1..cae5cc789 100644
--- a/modules/system/system.test
+++ b/modules/system/system.test
@@ -867,6 +867,44 @@ class CronRunTestCase extends DrupalWebTestCase {
}
}
+/**
+ * Test execution of the cron queue.
+ */
+class CronQueueTestCase extends DrupalWebTestCase {
+ /**
+ * Implement getInfo().
+ */
+ public static function getInfo() {
+ return array(
+ 'name' => 'Cron queue functionality',
+ 'description' => 'Tests the cron queue runner.',
+ 'group' => 'System'
+ );
+ }
+
+ function setUp() {
+ parent::setUp(array('common_test', 'common_test_cron_helper'));
+ }
+
+ /**
+ * Tests that exceptions thrown by workers are handled properly.
+ */
+ function testExceptions() {
+ $queue = DrupalQueue::get('cron_queue_test_exception');
+
+ // Enqueue an item for processing.
+ $queue->createItem(array($this->randomName() => $this->randomName()));
+
+ // Run cron; the worker for this queue should throw an exception and handle
+ // it.
+ $this->cronRun();
+
+ // The item should be left in the queue.
+ $this->assertEqual($queue->numberOfItems(), 1, 'Failing item still in the queue after throwing an exception.');
+ }
+
+}
+
class AdminMetaTagTestCase extends DrupalWebTestCase {
/**
* Implement getInfo().
diff --git a/modules/system/tests/cron_queue_test.info b/modules/system/tests/cron_queue_test.info
new file mode 100644
index 000000000..718cb10d3
--- /dev/null
+++ b/modules/system/tests/cron_queue_test.info
@@ -0,0 +1,6 @@
+name = Cron Queue test
+description = 'Support module for the cron queue runner.'
+package = Testing
+version = VERSION
+core = 7.x
+hidden = TRUE
diff --git a/modules/system/tests/cron_queue_test.module b/modules/system/tests/cron_queue_test.module
new file mode 100644
index 000000000..e95c6b6af
--- /dev/null
+++ b/modules/system/tests/cron_queue_test.module
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * Implements hook_cron_queue_info().
+ */
+function cron_queue_test_cron_queue_info() {
+ $queues['cron_queue_test_exception'] = array(
+ 'worker callback' => 'cron_queue_test_exception',
+ );
+ return $queues;
+}
+
+function cron_queue_test_exception($item) {
+ throw new Exception('That is not supposed to happen.');
+}