=== modified file 'datasync.job.inc'
--- datasync.job.inc	2009-07-29 15:34:25 +0000
+++ datasync.job.inc	2009-08-03 14:25:39 +0000
@@ -138,11 +138,16 @@
         $this->start_transaction();
       }
       
-      //THIS ACTUALLY RUNS THE PHASE
-      $result = $this->{$this->phase}();
+      try {
+        //THIS ACTUALLY RUNS THE PHASE
+        $result = $this->{$this->phase}();
+      }
+      catch (Exception $e) {
+        $result = t("Exception caught: %exception", array('%exception' => $e->getMessage()));
+      }
       
       if ($phase_uses_transaction) {
-        if ($result) {
+        if ($result === TRUE) {
           $this->commit_transaction();
         }
         else {
@@ -150,7 +155,7 @@
         }
       }
  
-      if (!$result) {
+      if ($result !== TRUE) {
         datasync_debug('phase failed');  
         $this->fail_phase();
         throw new DataSyncException("Ran phase !p but it did not return a TRUE result. It returned !r", array('!p' => $this->phase, '!r' => $result), 0, $this);
@@ -239,28 +244,48 @@
   
   /**
    * Take action because of a phase fail. This could mean starting from the initial phase,
-   * restarting the current phase, or ending the job. Right now the default implementation only restarts the 
-   * current phase.
+   * restarting the current phase, or ending the job. The default implementation only restarts the 
+   * current phase. If you decide you want to use a method other then the default, you should
+   * override your job type's fail_phase method and call parent::fail_phase($method) from it. As
+   * always, you can override the method and define your own custom behavior without referencing
+   * parent.
    * 
    * @param $method
-   *   Not in use yet. Defines what action on fail you want
+   *   DataSync provides 3 default methods of failing a phase:
+   *   - restart_phase: sets the current phase back to the beginning to be run again.
+   *   - fail_job: fails the job which will never be ran again.
+   *   - restart_job: sets the job back to the beginning phase and queues for rerun.
    *   
    * @return
    *   true on success
    */
-  public function fail_phase($method = NULL) {
+  public function fail_phase($method = 'restart_phase') {
     datasync_debug("fail_phase called on $this->job_id. method: $method");
-    //right now we only restart the current phase
     $this->start_transaction();
     $this->construct_from_db();
-    $this->doing_phase = FALSE;
-    $this->switch_phase($this->phase);
+    switch ($method) {
+      case 'fail_job':
+        $this->doing_phase = FALSE;
+        $this->switch_phase('datasync_failed');
+        $this->switch_next_phase('datasync_failed');
+      break;
+      case 'restart_job':
+        $this->doing_phase = FALSE;
+        $this->switch_phase('datasync_restarted');
+        $this->switch_next_phase();
+      break;
+      case 'restart_phase':
+      default:
+        //right now we only restart the current phase
+        $this->doing_phase = FALSE;
+        $this->switch_phase($this->phase);
+      break;
+    }
     //refetch new data
     $this->construct_from_db(TRUE);
     $this->commit_transaction();
     
-    module_invoke_all('datasync_phase_failed', $this);
-    
+    module_invoke_all('datasync_phase_failed', $this, $method);
     return TRUE;
   }
   
@@ -353,8 +378,11 @@
     }
     $tmp = $this->phases;
     ksort($tmp);
-    //if the phase is added, 
-    if ($this->phase == 'datasync_added') {
+    if ($this->phase == 'datasync_failed') {
+      return 'datasync_failed';
+    }
+    //if the phase is added or restarted, just start the first phase
+    if ($this->phase == 'datasync_added' || $this->phase == 'datasync_restarted') {
       return array_shift($tmp);
     }
     $next = FALSE;
@@ -401,7 +429,7 @@
     }
     
     //UNSTARTED == 0
-    $query = "SELECT job_id FROM {datasync_jobs} WHERE started=0 AND phase!='datasync_done' ";
+    $query = "SELECT job_id FROM {datasync_jobs} WHERE started=0 AND phase!='datasync_done' AND phase!='datasync_failed'";
     if (count($filters)) {
       $query .= 'AND ( (' . implode(') OR (', $filters) . ' ) ) ';
     }

