diff --git a/includes/common.inc b/includes/common.inc
index a443158..1c55f34 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 f4fb047..cae5cc7 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 0000000..718cb10
--- /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 0000000..e95c6b6
--- /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.');
+}
