diff --git a/include/class_ldap.inc b/include/class_ldap.inc
index 01626af72e74ca38d7dc340750e60bbffd46e238..e9e6c310965641eb84062e18cd00a09e471cf57f 100644
--- a/include/class_ldap.inc
+++ b/include/class_ldap.inc
@@ -949,8 +949,7 @@ class LDAP
 
           /* Bail out, if we've nothing to do... */
           if ($ocname == '') {
-            msg_dialog::display(_('Internal error'), sprintf(_('Cannot automatically create subtrees with RDN "%s": no object class found!'), $type), FATAL_ERROR_DIALOG);
-            exit();
+            throw new FusionDirectoryError(htmlescape(sprintf(_('Cannot automatically create subtrees with RDN "%s": no object class found!'), $type)));
           }
 
           /* Assemble_entry */
@@ -987,8 +986,7 @@ class LDAP
               $na['o']            = $param;
               break;
             default:
-              msg_dialog::display(_('Internal error'), sprintf(_('Cannot automatically create subtrees with RDN "%s": not supported'), $type), FATAL_ERROR_DIALOG);
-              exit();
+              throw new FusionDirectoryError(htmlescape(sprintf(_('Cannot automatically create subtrees with RDN "%s": not supported'), $type)));
           }
         }
         $this->cd($cdn);
@@ -999,13 +997,10 @@ class LDAP
           logging::debug(DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__, $na, 'Content');
           logging::debug(DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__, $this->get_error(), 'LDAP error');
 
-          msg_dialog::display(_('LDAP error'), msgPool::ldaperror($this->get_error(), $cdn, LDAP_ADD, get_class()), LDAP_ERROR);
-          return FALSE;
+          throw new SimplePluginLdapError(NULL, $cdn, LDAP_ADD, $this->get_error(), $this->get_errno());
         }
       }
     }
-
-    return TRUE;
   }
 
 
@@ -1334,7 +1329,11 @@ class LDAP
 
       /* Create missing trees */
       $this->cd($config->current['BASE']);
-      $this->create_missing_trees($srp, preg_replace('/^[^,]+,/', '', $dn));
+      try {
+        $this->create_missing_trees($srp, preg_replace('/^[^,]+,/', '', $dn));
+      } catch (FusionDirectoryError $error) {
+        $error->display();
+      }
       $this->cd($dn);
 
       if (!$modify) {
diff --git a/include/class_passwordRecovery.inc b/include/class_passwordRecovery.inc
index fc1f73157a4c3b3df8a62d736d02c41695a39c04..bc532a2c0b2261aeb2fdaa8eed7dcc8285888889 100644
--- a/include/class_passwordRecovery.inc
+++ b/include/class_passwordRecovery.inc
@@ -168,15 +168,10 @@ class passwordRecovery extends standAlonePage
     if (!$ldap->count()) {
       /* It's not, let's create it */
       $ldap->cd($config->current['BASE']);
-      $ldap->create_missing_trees($token);
-      if (!$ldap->success()) {
-        return new SimplePluginLdapError(
-          NULL,
-          $token,
-          NULL,
-          $ldap->get_error(),
-          $ldap->get_errno()
-        );
+      try {
+        $ldap->create_missing_trees($token);
+      } catch (FusionDirectoryError $error) {
+        return $error;
       }
       fusiondirectory_log("Created token branch ".$token);
     }
diff --git a/include/errors/class_FusionDirectoryError.inc b/include/errors/class_FusionDirectoryError.inc
index a846a6402f5c4bdd8cc1e8675a6231f4d765fef2..432d690f3fb45e6dbfcfe5fec1df0da6921d9270 100644
--- a/include/errors/class_FusionDirectoryError.inc
+++ b/include/errors/class_FusionDirectoryError.inc
@@ -31,6 +31,11 @@ class FusionDirectoryError extends Error
     parent::__construct(htmlunescape(strip_tags($htmlMessage)), $code, $previous);
   }
 
+  public function getHtmlMessage ()
+  {
+    return $this->htmlMessage;
+  }
+
   public function toArray (): array
   {
     return [
@@ -39,4 +44,24 @@ class FusionDirectoryError extends Error
       'file'    => $this->getFile(),
     ];
   }
+
+  public function computeMsgDialogParameters (): array
+  {
+    $trace = $this->getTrace();
+
+    array_unshift(
+      $trace,
+      [
+        'file' => $this->getFile(),
+        'line' => $this->getLine(),
+      ]
+    );
+
+    return [_('Error'), $this->htmlMessage, ERROR_DIALOG, $trace];
+  }
+
+  public function display ()
+  {
+    msg_dialog::display(...$this->computeMsgDialogParameters());
+  }
 }
diff --git a/include/errors/class_SimplePluginError.inc b/include/errors/class_SimplePluginError.inc
index a67eebb1f47eadc55f0a9611dd2457daab5f7443..57709e9082f0381c061c1e0180fa296acfc2fb9b 100644
--- a/include/errors/class_SimplePluginError.inc
+++ b/include/errors/class_SimplePluginError.inc
@@ -28,6 +28,13 @@ class SimplePluginError extends FusionDirectoryError
   protected $attribute;
 
   public function __construct ($origin, string $htmlMessage = '', int $code = 0, Throwable $previous = NULL)
+  {
+    $this->setOrigin($origin);
+
+    parent::__construct($htmlMessage, $code, $previous);
+  }
+
+  public function setOrigin ($origin)
   {
     if ($origin instanceof Attribute) {
       $this->attribute  = $origin;
@@ -43,8 +50,6 @@ class SimplePluginError extends FusionDirectoryError
         $this->object = $origin;
       }
     }
-
-    parent::__construct($htmlMessage, $code, $previous);
   }
 
   public function toArray (): array
@@ -109,4 +114,14 @@ class SimplePluginError extends FusionDirectoryError
 
     return [_('Error'), $html, ERROR_DIALOG, $trace];
   }
+
+  public static function relocate ($origin, FusionDirectoryError $error)
+  {
+    if ($error instanceof SimplePluginError) {
+      $error->setOrigin($origin);
+      return $error;
+    } else {
+      return new SimplePluginError($origin, $error->getHtmlMessage(), $error->getCode(), $error);
+    }
+  }
 }
diff --git a/include/functions.inc b/include/functions.inc
index 29d1937692681af19ae45406058d4c0b0a6c3615..8af0c9ab12d81c75181c6b42d1ac7fcd0c67ce65 100644
--- a/include/functions.inc
+++ b/include/functions.inc
@@ -419,7 +419,11 @@ function add_lock ($object, $user)
   if ($ldap->get_errno() == 32) {
     /* No such object, means the locking branch is missing, create it */
     $ldap->cd($config->current['BASE']);
-    $ldap->create_missing_trees(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
+    try {
+      $ldap->create_missing_trees(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
+    } catch (FusionDirectoryError $error) {
+      $error->display();
+    }
     $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
     $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($user).')(fdObjectDn='.base64_encode($object).'))',
       ['fdUserDn']);
diff --git a/include/login/class_LoginMethod.inc b/include/login/class_LoginMethod.inc
index 31b969f2130793ebf16c5765b56f46b0d321f218..dc71610a1ccbdbd86d6b55e8e2f1ee0d70363cf8 100644
--- a/include/login/class_LoginMethod.inc
+++ b/include/login/class_LoginMethod.inc
@@ -69,7 +69,11 @@ class LoginMethod
     $attrs = $ldap->fetch();
     if (!count($attrs)) {
       $ldap->cd($config->current['BASE']);
-      $ldap->create_missing_trees(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
+      try {
+        $ldap->create_missing_trees(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
+      } catch (FusionDirectoryError $error) {
+        $error->display();
+      }
     }
   }
 
diff --git a/include/management/snapshot/class_SnapshotHandler.inc b/include/management/snapshot/class_SnapshotHandler.inc
index 6c39cf00c570a25c6669943030ca5adc1cb076ea..2c6f1618f67f1fe89f0bc10475aed3fafc67d05d 100644
--- a/include/management/snapshot/class_SnapshotHandler.inc
+++ b/include/management/snapshot/class_SnapshotHandler.inc
@@ -60,9 +60,10 @@ class SnapshotHandler
       $this->snapshotRDN = $config->get_cfg_value('snapshotBase');
       $ldap = $config->get_ldap_link();
       $ldap->cd($config->current['BASE']);
-      $ldap->create_missing_trees($this->snapshotRDN);
-      if (!$ldap->success()) {
-        msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), $this->snapshotRDN, '', get_class()), LDAP_ERROR);
+      try {
+        $ldap->create_missing_trees($this->snapshotRDN);
+      } catch (FusionDirectoryError $error) {
+        $error->display();
       }
     }
   }
@@ -254,8 +255,12 @@ class SnapshotHandler
 
     /* Insert this new snapshot */
     $ldap->cd($this->snapshotRDN);
-    $ldap->create_missing_trees($this->snapshotRDN);
-    $ldap->create_missing_trees($new_base);
+    try {
+      $ldap->create_missing_trees($this->snapshotRDN);
+      $ldap->create_missing_trees($new_base);
+    } catch (FusionDirectoryError $error) {
+      $error->display();
+    }
     $ldap->cd($new_dn);
     $ldap->add($target);
 
diff --git a/include/simpleplugin/attributes/class_SetAttribute.inc b/include/simpleplugin/attributes/class_SetAttribute.inc
index f762669042c1899e73f6e8b0cb4538bf0ef92b66..c82c4faa2255813b66427be1ef3d4489cca866cf 100644
--- a/include/simpleplugin/attributes/class_SetAttribute.inc
+++ b/include/simpleplugin/attributes/class_SetAttribute.inc
@@ -669,7 +669,7 @@ class OrderedArrayAttribute extends SetAttribute
         if (is_string($error)) {
           msg_dialog::display(sprintf(_('Invalid value for %s'), $this->getLabel()), $error);
         } else {
-          msg_dialog::display($error);
+          $error->display();
         }
       } else {
         $this->addPostValue($this->attribute->getValue());
diff --git a/include/simpleplugin/class_simplePlugin.inc b/include/simpleplugin/class_simplePlugin.inc
index c4b097455063e1763248152ec3b9d4d7507af487..a7493931dcbf6c288a262fbf96317c44ff4add22 100644
--- a/include/simpleplugin/class_simplePlugin.inc
+++ b/include/simpleplugin/class_simplePlugin.inc
@@ -589,7 +589,11 @@ class simplePlugin implements SimpleTab
     /* Try to move with ldap routines */
     $ldap = $config->get_ldap_link();
     $ldap->cd($config->current['BASE']);
-    $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $dst_dn));
+    try {
+      $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $dst_dn));
+    } catch (FusionDirectoryError $error) {
+      $error->display();
+    }
     if (!$ldap->rename_dn($src_dn, $dst_dn)) {
       logging::log('error', 'ldap', "FROM: $src_dn -- TO: $dst_dn", [], 'Ldap Protocol v3 implementation error, ldap_rename failed: '.$ldap->get_error());
       logging::debug(DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__, "Rename failed FROM: $src_dn  -- TO:  $dst_dn",
@@ -1386,7 +1390,11 @@ class simplePlugin implements SimpleTab
         ];
       }
       $ldap->cd($config->current['BASE']);
-      $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
+      try {
+        $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
+      } catch (FusionDirectoryError $error) {
+        return [$error];
+      }
       $action = 'add';
     } else {
       if (!$ldap->dn_exists($this->dn)) {
diff --git a/plugins/config/class_recoveryConfig.inc b/plugins/config/class_recoveryConfig.inc
index 721fd51ff47c60e4144dc865391f230d8189f5b7..a27371d380558449936cc140e85b61f7617dd9db 100644
--- a/plugins/config/class_recoveryConfig.inc
+++ b/plugins/config/class_recoveryConfig.inc
@@ -132,13 +132,10 @@ class recoveryConfig extends simplePlugin
     $ldap->cat($tokenBranch, ['dn']);
     if (!$ldap->count()) {
       $ldap->cd($config->current['BASE']);
-      $ldap->create_missing_trees($tokenBranch);
-      if (!$ldap->success()) {
-        msg_dialog::display(
-          _('LDAP error'),
-          msgPool::ldaperror($ldap->get_error(), $tokenBranch, LDAP_MOD, get_class()),
-          LDAP_ERROR
-        );
+      try {
+        $ldap->create_missing_trees($tokenBranch);
+      } catch (FusionDirectoryError $error) {
+        $error->display();
       }
       fusiondirectory_log('Created token branch '.$tokenBranch);
     }
diff --git a/setup/class_setupStepConfig.inc b/setup/class_setupStepConfig.inc
index a43d81c6e30c2994e807cc686fac525cfae0fb1e..d99974d3006786bf016ffa333218d2c0518442dc 100644
--- a/setup/class_setupStepConfig.inc
+++ b/setup/class_setupStepConfig.inc
@@ -104,13 +104,10 @@ class setupStepConfig extends configInLdap
       /* Create root object if missing */
       $ldap = $config->get_ldap_link();
       $ldap->cd($config->current['BASE']);
-      $ldap->create_missing_trees($config->current['BASE'], FALSE);
-      if (!$ldap->success()) {
-        msg_dialog::display(
-          _('LDAP error'),
-          msgPool::ldaperror($ldap->get_error(), $config->current['BASE'], 'create_missing_trees', get_class()),
-          LDAP_ERROR
-        );
+      try {
+        $ldap->create_missing_trees($config->current['BASE'], FALSE);
+      } catch (FusionDirectoryError $error) {
+        $error->display();
         return;
       }
       /* Save in LDAP */
diff --git a/setup/class_setupStepMigrate.inc b/setup/class_setupStepMigrate.inc
index b350efdfe8bc49d34e4cfe5df3f3db03f373e118..59f3c844dcdb81800e39a9cf4c10265f8f43b573 100644
--- a/setup/class_setupStepMigrate.inc
+++ b/setup/class_setupStepMigrate.inc
@@ -973,7 +973,11 @@ class setupStepMigrate extends setupStep
       $ldap->cat($dn);
       if ($ldap->count() == 0) {
         $ldap->cd($config->current['BASE']);
-        $ldap->create_missing_trees(get_ou('aclRoleRDN').$config->current['BASE']);
+        try {
+          $ldap->create_missing_trees(get_ou('aclRoleRDN').$config->current['BASE']);
+        } catch (FusionDirectoryError $error) {
+          $error->display();
+        }
         $ldap->cd($dn);
         $ldap->add($role);
         if (!$ldap->success()) {