diff --git a/src/mesh/GmshReader.cpp b/src/mesh/GmshReader.cpp
index cf1706c9c54c727f884ae151817e486f17404201..0d38e108bda1fdfa2be5bc5d3a742648ca3ccdc6 100644
--- a/src/mesh/GmshReader.cpp
+++ b/src/mesh/GmshReader.cpp
@@ -9,9 +9,7 @@
 #include <mesh/Mesh.hpp>
 #include <mesh/MeshData.hpp>
 #include <mesh/RefItemList.hpp>
-
 #include <utils/ArrayUtils.hpp>
-
 #include <utils/Exceptions.hpp>
 
 #include <rang.hpp>
@@ -19,113 +17,12 @@
 #include <fstream>
 #include <iomanip>
 #include <iostream>
-#include <set>
-#include <sstream>
-
 #include <map>
 #include <regex>
+#include <set>
+#include <sstream>
 #include <unordered_map>
 
-class ErrorHandler
-{
- public:
-  enum Type
-  {
-    asked,       /**< execution request by the user*/
-    compilation, /**< syntax error in a language */
-    normal,      /**< normal error due to a bad use of ff3d */
-    unexpected   /**< Unexpected execution error */
-  };
-
- private:
-  const std::string __filename;     /**< The source file name where the error occured */
-  const size_t __lineNumber;        /**< The line number where exception was raised */
-  const std::string __errorMessage; /**< The reporting message */
-
-  const Type __type; /**< the type of the error */
- public:
-  /**
-   * Prints the error message
-   *
-   */
-  virtual void writeErrorMessage() const;
-
-  /**
-   * The copy constructor
-   *
-   * @param e an handled error
-   */
-  ErrorHandler(const ErrorHandler& e)
-    : __filename(e.__filename), __lineNumber(e.__lineNumber), __errorMessage(e.__errorMessage), __type(e.__type)
-  {
-    ;
-  }
-
-  /**
-   * Constructor
-   *
-   * @param filename the source file name
-   * @param lineNumber the source line
-   * @param errorMessage the reported message
-   * @param type the type of the error
-   */
-  ErrorHandler(const std::string& filename,
-               const size_t& lineNumber,
-               const std::string& errorMessage,
-               const Type& type);
-
-  /**
-   * The destructor
-   *
-   */
-  virtual ~ErrorHandler()
-  {
-    ;
-  }
-};
-
-void
-ErrorHandler::writeErrorMessage() const
-{
-  switch (__type) {
-  case asked: {
-    std::cerr << "\nremark: exit command explicitly called\n";
-    [[fallthrough]];
-  }
-  case normal: {
-    std::cerr << '\n' << __filename << ':' << __lineNumber << ":remark: emitted the following message\n";
-    std::cerr << "error: " << __errorMessage << '\n';
-    break;
-  }
-  case compilation: {
-    std::cerr << "\nline " << __lineNumber << ':' << __errorMessage << '\n';
-    break;
-  }
-  case unexpected: {
-    std::cerr << '\n' << __filename << ':' << __lineNumber << ":\n" << __errorMessage << '\n';
-    std::cerr << "\nUNEXPECTED ERROR: this should not occure, please report it\n";
-    std::cerr << "\nBUG REPORT: Please send bug reports to:\n"
-              << "  ff3d-dev@nongnu.org or freefem@ann.jussieu.fr\n"
-              << "or better, use the Bug Tracking System:\n"
-              << "  http://savannah.nongnu.org/bugs/?group=ff3d\n";
-    break;
-  }
-  default: {
-    std::cerr << __filename << ':' << __lineNumber << ": " << __errorMessage << '\n';
-    std::cerr << __FILE__ << ':' << __LINE__ << ":remark:  error type not implemented!\n";
-  }
-  }
-}
-
-ErrorHandler::ErrorHandler(const std::string& filename,
-                           const size_t& lineNumber,
-                           const std::string& errorMessage,
-                           const Type& type)
-  : __filename(filename), __lineNumber(lineNumber), __errorMessage(errorMessage), __type(type)
-{
-  ;
-}
-
 template <int Dimension>
 void
 GmshReader::_dispatch()
@@ -575,8 +472,7 @@ GmshReader::__readElements2_2()
   const int numberOfElements = this->_getInteger();
   std::cout << "- Number Of Elements: " << numberOfElements << '\n';
   if (numberOfElements < 0) {
-    throw ErrorHandler(__FILE__, __LINE__, "reading file '" + m_filename + "': number of elements is negative",
-                       ErrorHandler::normal);
+    throw NormalError("reading file '" + m_filename + "': number of elements is negative");
   }
 
   __elementNumber.resize(numberOfElements);
@@ -590,10 +486,8 @@ GmshReader::__readElements2_2()
       const int elementType = this->_getInteger() - 1;
 
       if ((elementType < 0) or (elementType > 14)) {
-        throw ErrorHandler(__FILE__, __LINE__,
-                           "reading file '" + m_filename + "': unknown element type '" + std::to_string(elementType) +
-                             "'",
-                           ErrorHandler::normal);
+        throw NormalError("reading file '" + m_filename + "': unknown element type '" + std::to_string(elementType) +
+                          "'");
       }
       __elementType[i]       = elementType;
       const int numberOfTags = this->_getInteger();
@@ -1059,9 +953,7 @@ GmshReader::__proceedData()
         case 12:   // second order prism
         case 13:   // second order pyramid
         default: {
-          throw ErrorHandler(__FILE__, __LINE__,
-                             "reading file '" + m_filename + "': ff3d cannot read this kind of element",
-                             ErrorHandler::normal);
+          throw NormalError("reading file '" + m_filename + "': ff3d cannot read this kind of element");
         }
         }
       }
@@ -1079,11 +971,7 @@ GmshReader::__proceedData()
   }
 
   if (minNumber < 0) {
-    throw ErrorHandler(__FILE__, __LINE__,
-                       "reading file '" + m_filename +
-                         "': ff3d does not implement negative vertices "
-                         "number",
-                       ErrorHandler::normal);
+    throw NotImplementedError("reading file '" + m_filename + "': negative vertices number");
   }
 
   // A value of -1 means that the vertex is unknown
@@ -1106,10 +994,8 @@ GmshReader::__proceedData()
       const int a     = __verticesCorrepondance[elementVertices[0]];
       const int b     = __verticesCorrepondance[elementVertices[1]];
       if ((a < 0) or (b < 0)) {
-        throw ErrorHandler(__FILE__, __LINE__,
-                           "reading file '" + m_filename + "': error reading element " + std::to_string(i) +
-                             " [bad vertices definition]",
-                           ErrorHandler::normal);
+        throw NormalError("reading file '" + m_filename + "': error reading element " + std::to_string(i) +
+                          " [bad vertices definition]");
       }
       __edges[edgeNumber]        = Edge(a, b);
       __edges_ref[edgeNumber]    = __references[i];
@@ -1124,10 +1010,8 @@ GmshReader::__proceedData()
       const int b = __verticesCorrepondance[elementVertices[1]];
       const int c = __verticesCorrepondance[elementVertices[2]];
       if ((a < 0) or (b < 0) or (c < 0)) {
-        throw ErrorHandler(__FILE__, __LINE__,
-                           "reading file '" + m_filename + "': error reading element " + std::to_string(i) +
-                             " [bad vertices definition]",
-                           ErrorHandler::normal);
+        throw NormalError("reading file '" + m_filename + "': error reading element " + std::to_string(i) +
+                          " [bad vertices definition]");
       }
       __triangles[triangleNumber]        = Triangle(a, b, c);
       __triangles_ref[triangleNumber]    = __references[i];
@@ -1143,10 +1027,8 @@ GmshReader::__proceedData()
       const int c = __verticesCorrepondance[elementVertices[2]];
       const int d = __verticesCorrepondance[elementVertices[3]];
       if ((a < 0) or (b < 0) or (c < 0) or (d < 0)) {
-        throw ErrorHandler(__FILE__, __LINE__,
-                           "reading file '" + m_filename + "': error reading element " + std::to_string(i) +
-                             " [bad vertices definition]",
-                           ErrorHandler::normal);
+        throw NormalError("reading file '" + m_filename + "': error reading element " + std::to_string(i) +
+                          " [bad vertices definition]");
       }
       __quadrangles[quadrilateralNumber]        = Quadrangle(a, b, c, d);
       __quadrangles_ref[quadrilateralNumber]    = __references[i];
@@ -1162,10 +1044,8 @@ GmshReader::__proceedData()
       const int c = __verticesCorrepondance[elementVertices[2]];
       const int d = __verticesCorrepondance[elementVertices[3]];
       if ((a < 0) or (b < 0) or (c < 0) or (d < 0)) {
-        throw ErrorHandler(__FILE__, __LINE__,
-                           "reading file '" + m_filename + "': error reading element " + std::to_string(i) +
-                             " [bad vertices definition]",
-                           ErrorHandler::normal);
+        throw NormalError("reading file '" + m_filename + "': error reading element " + std::to_string(i) +
+                          " [bad vertices definition]");
       }
       __tetrahedra[tetrahedronNumber]        = Tetrahedron(a, b, c, d);
       __tetrahedra_ref[tetrahedronNumber]    = __references[i];
@@ -1185,10 +1065,8 @@ GmshReader::__proceedData()
       const int g = __verticesCorrepondance[elementVertices[6]];
       const int h = __verticesCorrepondance[elementVertices[7]];
       if ((a < 0) or (b < 0) or (c < 0) or (d < 0) or (e < 0) or (f < 0) or (g < 0) or (h < 0)) {
-        throw ErrorHandler(__FILE__, __LINE__,
-                           "reading file '" + m_filename + "': error reading element " + std::to_string(i) +
-                             " [bad vertices definition]",
-                           ErrorHandler::normal);
+        throw NormalError("reading file '" + m_filename + "': error reading element " + std::to_string(i) +
+                          " [bad vertices definition]");
       }
       __hexahedra[hexahedronNumber]        = Hexahedron(a, b, c, d, e, f, g, h);
       __hexahedra_ref[hexahedronNumber]    = __references[i];
@@ -1217,8 +1095,7 @@ GmshReader::__proceedData()
     case 13: {   // second order pyramid
     }
     default: {
-      throw ErrorHandler(__FILE__, __LINE__, "reading file '" + m_filename + "': ff3d cannot read this kind of element",
-                         ErrorHandler::normal);
+      throw NormalError("reading file '" + m_filename + "': ff3d cannot read this kind of element");
     }
     }
   }
@@ -1736,8 +1613,7 @@ GmshReader::__nextKeyword()
     return kw;
   }
 
-  throw ErrorHandler(__FILE__, __LINE__, "reading file '" + m_filename + "': unknown keyword '" + aKeyword + "'",
-                     ErrorHandler::normal);
+  throw NormalError("reading file '" + m_filename + "': unknown keyword '" + aKeyword + "'");
 
   kw.first  = aKeyword;
   kw.second = Unknown;
@@ -1755,9 +1631,7 @@ GmshReader::__readGmshFormat2_2()
     case NODES: {
       this->__readVertices();
       if (this->__nextKeyword().second != ENDNODES) {
-        throw ErrorHandler(__FILE__, __LINE__,
-                           "reading file '" + m_filename + "': expecting $EndNodes, '" + kw.first + "' was found",
-                           ErrorHandler::normal);
+        throw NormalError("reading file '" + m_filename + "': expecting $EndNodes, '" + kw.first + "' was found");
       }
       break;
     }
@@ -1765,18 +1639,14 @@ GmshReader::__readGmshFormat2_2()
       this->__readElements2_2();
       kw = this->__nextKeyword();
       if (kw.second != ENDELEMENTS) {
-        throw ErrorHandler(__FILE__, __LINE__,
-                           "reading file '" + m_filename + "': expecting $EndElements, '" + kw.first + "' was found",
-                           ErrorHandler::normal);
+        throw NormalError("reading file '" + m_filename + "': expecting $EndElements, '" + kw.first + "' was found");
       }
       break;
     }
     case PHYSICALNAMES: {
       this->__readPhysicalNames2_2();
       if (this->__nextKeyword().second != ENDPHYSICALNAMES) {
-        throw ErrorHandler(__FILE__, __LINE__,
-                           "reading file '" + m_filename + "': expecting $EndNodes, '" + kw.first + "' was found",
-                           ErrorHandler::normal);
+        throw NormalError("reading file '" + m_filename + "': expecting $EndNodes, '" + kw.first + "' was found");
       }
       break;
     }
@@ -1785,8 +1655,7 @@ GmshReader::__readGmshFormat2_2()
       break;
     }
     default: {
-      throw ErrorHandler(__FILE__, __LINE__, "reading file '" + m_filename + "': unexpected '" + kw.first + "'",
-                         ErrorHandler::normal);
+      throw NormalError("reading file '" + m_filename + "': unexpected '" + kw.first + "'");
     }
     }
   }