=== modified file 'includes/update.inc'
--- includes/update.inc	2009-08-03 19:37:37 +0000
+++ includes/update.inc	2009-08-20 06:19:21 +0000
@@ -287,11 +287,21 @@ function update_parse_db_url($db_url) {
  * Perform one update and store the results which will later be displayed on
  * the finished page.
  *
- * An update function can force the current and all later updates for this
- * module to abort by returning a $ret array with an element like:
- * $ret['#abort'] = array('success' => FALSE, 'query' => 'What went wrong');
- * The schema version will not be updated in this case, and all the
- * aborted updates will continue to appear on update.php as updates that
+ * If an update function completes successfully, it should return a message
+ * as a string indicating success, for example:
+ * @code
+ * return t('New index added successfully.');
+ * @endcode
+ *
+ * If it fails for whatever reason, it should throw an instance of
+ * DrupalUpdateException with an appropriate error message, for example:
+ * @code
+ * throw new DrupalUpdateException(t('Description of what went wrong'));
+ * @endcode
+ *
+ * If an exception is thrown, the current and all later updates for this module
+ * will be aborded. The schema version will not be updated in this case, and all
+ * the aborted updates will continue to appear on update.php as updates that
  * have not yet been run.
  *
  * @param $module
@@ -308,9 +318,43 @@ function update_do_one($module, $number,
     return;
   }
 
+  if (!isset($context['log'])) {
+    $context['log'] = (bool) variable_get('update_log_queries', FALSE);
+  }
+
+  $ret = array();
   $function = $module . '_update_' . $number;
   if (function_exists($function)) {
-    $ret = $function($context['sandbox']);
+    try {
+      if ($context['log']) {
+        Database::startLog($function);
+      }
+      $ret = $function($context['sandbox']);
+    }
+    catch (DrupalUpdateException $e) {
+      $ret['results'] = array('success' => FALSE, 'query' => $e->getMessage());
+      $ret['#abort'] = TRUE;
+    }
+    catch (Exception $e) {
+      $ret['results'] = array('success' => FALSE, 'query' => $e->getMessage());
+      $ret['#abort'] = TRUE;
+    }
+
+    // @todo Remove after conversion of all core updates.
+    if (is_string($ret)) {
+      $ret = array(
+        'results' => array('success' => FALSE, 'query' => $ret),
+      );
+    }
+    elseif (!is_array($ret)) {
+      $ret = array(
+        'results' => array('success' => TRUE),
+      );
+    }
+
+    if ($context['log']) {
+      $ret['queries'] = Database::getLog($function);
+    }
   }
 
   if (isset($ret['#finished'])) {
@@ -338,6 +382,11 @@ function update_do_one($module, $number,
 }
 
 /**
+ * @class Exception class used to throw error if a module update fails.
+ */
+class DrupalUpdateException extends Exception { }
+
+/**
  * Start the database update batch process.
  *
  * @param $start
