From 05f77ccc6ea3a42c60cf945c261c06d09c3f6c2d Mon Sep 17 00:00:00 2001 From: webchick <webchick@24967.no-reply.drupal.org> Date: Tue, 30 Aug 2011 01:06:58 -0700 Subject: [PATCH] Issue #978944 by Aron Novak, chx, ksenzee: Fixed Handle exceptions thrown in cron. --- includes/common.inc | 10 +++++++++- modules/simpletest/tests/common_test.module | 13 +++++++++++++ .../tests/common_test_cron_helper.info | 6 ++++++ .../tests/common_test_cron_helper.module | 17 +++++++++++++++++ modules/system/system.test | 17 +++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 modules/simpletest/tests/common_test_cron_helper.info create mode 100644 modules/simpletest/tests/common_test_cron_helper.module diff --git a/includes/common.inc b/includes/common.inc index 1ef681f121a9..f54f29a7c39f 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -5041,7 +5041,15 @@ function drupal_cron_run() { drupal_register_shutdown_function('drupal_cron_cleanup'); // Iterate through the modules calling their cron handlers (if any): - module_invoke_all('cron'); + foreach (module_implements('cron') as $module) { + // Do not let an exception thrown by one module disturb another. + try { + module_invoke($module, 'cron'); + } + catch (Exception $e) { + watchdog_exception('cron', $e); + } + } // Record cron time variable_set('cron_last', REQUEST_TIME); diff --git a/modules/simpletest/tests/common_test.module b/modules/simpletest/tests/common_test.module index 9b6178804c90..c400eaed1142 100644 --- a/modules/simpletest/tests/common_test.module +++ b/modules/simpletest/tests/common_test.module @@ -225,3 +225,16 @@ function common_test_js_and_css_querystring() { drupal_add_css('/' . drupal_get_path('module', 'node') . '/node-fake.css?arg1=value1&arg2=value2'); return ''; } + +/** + * Implements hook_cron(). + * + * System module should handle if a module does not catch an exception and keep + * cron going. + * + * @see common_test_cron_helper() + * + */ +function common_test_cron() { + throw new Exception(t('Uncaught exception')); +} diff --git a/modules/simpletest/tests/common_test_cron_helper.info b/modules/simpletest/tests/common_test_cron_helper.info new file mode 100644 index 000000000000..ce1a6326fb33 --- /dev/null +++ b/modules/simpletest/tests/common_test_cron_helper.info @@ -0,0 +1,6 @@ +name = "Common Test Cron Helper" +description = "Helper module for CronRunTestCase::testCronExceptions()." +package = Testing +version = VERSION +core = 7.x +hidden = TRUE diff --git a/modules/simpletest/tests/common_test_cron_helper.module b/modules/simpletest/tests/common_test_cron_helper.module new file mode 100644 index 000000000000..94a2b2c43821 --- /dev/null +++ b/modules/simpletest/tests/common_test_cron_helper.module @@ -0,0 +1,17 @@ +<?php +/** + * @file + * Helper module for the testCronExceptions in addition to common_test module. + */ + +/** + * Implements hook_cron(). + * + * common_test_cron() throws an exception, but the execution should reach this + * function as well. + * + * @see common_test_cron() + */ +function common_test_cron_helper_cron() { + variable_set('common_test_cron', 'success'); +} diff --git a/modules/system/system.test b/modules/system/system.test index 181ddeafd29e..1ce8e6b7e0ed 100644 --- a/modules/system/system.test +++ b/modules/system/system.test @@ -695,6 +695,10 @@ class CronRunTestCase extends DrupalWebTestCase { ); } + function setUp() { + parent::setUp(array('common_test', 'common_test_cron_helper')); + } + /** * Test cron runs. */ @@ -799,6 +803,19 @@ class CronRunTestCase extends DrupalWebTestCase { $this->assertTrue(file_exists($perm_old->uri), t('Old permanent file was correctly ignored.')); $this->assertTrue(file_exists($perm_new->uri), t('New permanent file was correctly ignored.')); } + + /** + * Make sure exceptions thrown on hook_cron() don't affect other modules. + */ + function testCronExceptions() { + variable_del('common_test_cron'); + // The common_test module throws an exception. If it isn't caught, the tests + // won't finish successfully. + // The common_test_cron_helper module sets the 'common_test_cron' variable. + $this->cronRun(); + $result = variable_get('common_test_cron'); + $this->assertEqual($result, 'success', t('Cron correctly handles exceptions thrown during hook_cron() invocations.')); + } } class AdminMetaTagTestCase extends DrupalWebTestCase { -- GitLab