diff --git a/ChangeLog b/ChangeLog
index a5dcdbed28bc9341ff353e58603661341578b91a..33b6c3e35576c475bf770602fa20ec71d80a6dda 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -65,6 +65,7 @@ For users:
 - Fix: Add actions events not implemented.
 - Fix: Price min of composition is not supplier price min by quantity.
 - Fix: [ bug #1356 ] Bank accountancy number is limited to 8 numbers.
+- Fix: [ bug #1459 ] _ADD_CONTACT and _DEL_CONTACT triggers do not intercept insertion when reported an error
 
 TODO
 - New: Predefined product and free product use same form.
@@ -89,6 +90,8 @@ For developers:
 - New: A module can disable a standard ECM view.
 - New: Add multilang support into product webservice.
 - New: Add hooks on project card page.
+- New: Add call_trigger method on CommonObject class. So new trigger call within object it's just : 
+$result = $this->call_trigger($triger_name, $user) and do what you need to do if trigger fail 
 
 WARNING: Following change may create regression for some external modules, but was necessary to make
 Dolibarr better:
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 914d9be59a3b193aa0664f36b2c837ede30e61cf..0c1d18e28edfbc772d6a02f4e3baa7be04774d74 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -164,7 +164,6 @@ abstract class CommonObject
     {
         global $user,$conf,$langs;
 
-		$error=0;
 
         dol_syslog(get_class($this)."::add_contact $fk_socpeople, $type_contact, $source");
 
@@ -205,6 +204,8 @@ abstract class CommonObject
 
         $datecreate = dol_now();
 
+        $this->db->begin();
+        
         // Insertion dans la base
         $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_contact";
         $sql.= " (element_id, fk_socpeople, datecreate, statut, fk_c_type_contact) ";
@@ -219,20 +220,16 @@ abstract class CommonObject
         {
             if (! $notrigger)
             {
-                // Call triggers
-                include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-                $interface=new Interfaces($this->db);
-                $result=$interface->run_triggers(strtoupper($this->element).'_ADD_CONTACT',$this,$user,$langs,$conf);
-                if ($result < 0) {
-                    $error++; $this->errors=$interface->errors;
-                }
-                // End call triggers
+            	$result=$this->call_trigger(strtoupper($this->element).'_ADD_CONTACT', $user);
+	            if ($result < 0) { $this->db->rollback(); return -1; }
             }
-
+            
+            $this->db->commit();
             return 1;
         }
         else
         {
+            $this->db->rollback();
             if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
             {
                 $this->error=$this->db->errno();
@@ -311,8 +308,9 @@ abstract class CommonObject
     {
         global $user,$langs,$conf;
 
-		$error=0;
 
+        $this->db->begin();
+        
         $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_contact";
         $sql.= " WHERE rowid =".$rowid;
 
@@ -321,21 +319,17 @@ abstract class CommonObject
         {
             if (! $notrigger)
             {
-                // Call triggers
-                include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-                $interface=new Interfaces($this->db);
-                $result=$interface->run_triggers(strtoupper($this->element).'_DELETE_CONTACT',$this,$user,$langs,$conf);
-                if ($result < 0) {
-                    $error++; $this->errors=$interface->errors;
-                }
-                // End call triggers
+            	$result=$this->call_trigger(strtoupper($this->element).'_DELETE_CONTACT', $user);
+	            if ($result < 0) { $this->db->rollback(); return -1; }
             }
 
+            $this->db->commit();
             return 1;
         }
         else
         {
             $this->error=$this->db->lasterror();
+            $this->db->rollback();
             dol_syslog(get_class($this)."::delete_contact error=".$this->error, LOG_ERR);
             return -1;
         }
@@ -3354,8 +3348,9 @@ abstract class CommonObject
 	{
 	    global $user,$langs,$conf;
 
-	    $error=0;
 
+	    $this->db->begin();
+	    
 	    $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_resources";
 	    $sql.= " WHERE rowid =".$rowid;
 
@@ -3364,14 +3359,8 @@ abstract class CommonObject
 	    {
 	        if (! $notrigger)
 	        {
-	            // Call triggers
-	            include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-	            $interface=new Interfaces($this->db);
-	            $result=$interface->run_triggers(strtoupper($element).'_DELETE_RESOURCE',$this,$user,$langs,$conf);
-	            if ($result < 0) {
-	                $error++; $this->errors=$interface->errors;
-	            }
-	            // End call triggers
+	            $result=$this->call_trigger(strtoupper($element).'_DELETE_RESOURCE', $user);
+	            if ($result < 0) { $this->db->rollback(); return -1; }
 	        }
 
 	        return 1;
@@ -3379,6 +3368,7 @@ abstract class CommonObject
 	    else
 	    {
 	        $this->error=$this->db->lasterror();
+	        $this->db->rollback();
 	        dol_syslog(get_class($this)."::delete_resource error=".$this->error, LOG_ERR);
 	        return -1;
 	    }
@@ -3402,5 +3392,36 @@ abstract class CommonObject
         	}
         }
     }
+    
+    /**
+     * Call trigger based on this instance
+     * 
+     *  NB: Error from trigger are stacked in errors
+     *  NB2: if trigger fail, action should be canceled.
+     * 
+     * @param   string    $trigger_name   trigger's name to execute
+     * @param   User      $user           Object user
+     * @return  int                       Result of run_triggers
+     */
+    function call_trigger($trigger_name, $user)
+    {
+        global $langs,$conf;
+        
+        include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+        $interface=new Interfaces($this->db);
+        $result=$interface->run_triggers($trigger_name,$this,$user,$langs,$conf);
+        if ($result < 0) {
+            if (!empty($this->errors))
+            {
+                $this->errors=array_merge($this->errors,$interface->errors);
+            }
+            else 
+            {
+                $this->errors=$interface->errors;
+            }
+        }
+        return $result;
+        
+    }
 
 }