diff --git a/core/includes/common.inc b/core/includes/common.inc index db03ed9fb3537b158676153c283539bf3e17d1fc..36941822efea4ab481785826e255c191e442ac34 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3247,8 +3247,15 @@ function drupal_cron_run() { $end = time() + (isset($info['cron']['time']) ? $info['cron']['time'] : 15); $queue = \Drupal::queue($queue_name); while (time() < $end && ($item = $queue->claimItem())) { - call_user_func_array($callback, array($item->data)); - $queue->deleteItem($item); + try { + call_user_func_array($callback, array($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); + } } } } diff --git a/core/modules/system/lib/Drupal/system/Tests/System/CronQueueTest.php b/core/modules/system/lib/Drupal/system/Tests/System/CronQueueTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c62d519b04cbfc81f0d07404dd36be52eab4e9a4 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/System/CronQueueTest.php @@ -0,0 +1,53 @@ + 'Cron Queue functionality', + 'description' => 'Tests the Cron Queue runner.', + 'group' => 'Queue', + ); + } + + /** + * Tests that exceptions thrown by workers are handled properly. + */ + public function testExceptions() { + + $queue = $this->container->get('queue')->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.'); + } +} diff --git a/core/modules/system/tests/modules/cron_queue_test/cron_queue_test.info.yml b/core/modules/system/tests/modules/cron_queue_test/cron_queue_test.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..2d6dfa3bef3c2b13313c30b1e39424844ea9a50b --- /dev/null +++ b/core/modules/system/tests/modules/cron_queue_test/cron_queue_test.info.yml @@ -0,0 +1,7 @@ +name: 'Cron Queue test' +type: module +description: 'Support module for the cron queue runner.' +package: Testing +version: VERSION +core: 8.x +hidden: true diff --git a/core/modules/system/tests/modules/cron_queue_test/cron_queue_test.module b/core/modules/system/tests/modules/cron_queue_test/cron_queue_test.module new file mode 100644 index 0000000000000000000000000000000000000000..b88892feaf66cedcf3f83dc66fc280ddc45eeaae --- /dev/null +++ b/core/modules/system/tests/modules/cron_queue_test/cron_queue_test.module @@ -0,0 +1,17 @@ + t('Exception test'), + 'worker callback' => 'cron_queue_test_exception', + // Only needed if this queue should be processed by cron. + 'cron' => array( + 'time' => 60, + ), + ); + return $queues; +} + +function cron_queue_test_exception($item) { + throw new Exception('That is not supposed to happen.'); +}