diff options
author | David Rothstein <drothstein@gmail.com> | 2014-05-05 17:10:24 -0400 |
---|---|---|
committer | David Rothstein <drothstein@gmail.com> | 2014-05-05 17:10:24 -0400 |
commit | 07a910ede989af178d98c92aff7080bc027a06ce (patch) | |
tree | 980bd90370f2ba1d32e5dc1a5d569b3c3aa517ec | |
parent | 808a61aef282f43f55bf9d8db1de8d947f32e357 (diff) | |
download | brdo-07a910ede989af178d98c92aff7080bc027a06ce.tar.gz brdo-07a910ede989af178d98c92aff7080bc027a06ce.tar.bz2 |
Issue #2021933 by Crell, David_Rothstein, joachim, lz1irq: Catch exceptions from queue workers.
-rw-r--r-- | CHANGELOG.txt | 2 | ||||
-rw-r--r-- | includes/common.inc | 11 | ||||
-rw-r--r-- | modules/system/system.test | 38 | ||||
-rw-r--r-- | modules/system/tests/cron_queue_test.info | 6 | ||||
-rw-r--r-- | modules/system/tests/cron_queue_test.module | 15 |
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.'); +} |