diff --git a/Applications/ApplicationsLib/LogogSetup.h b/Applications/ApplicationsLib/LogogSetup.h
index 2a67d5c638bd888544dd74097d91301ea4ecb83a..88b6a81ba710f5930c316c642032cb846bb7a7fb 100644
--- a/Applications/ApplicationsLib/LogogSetup.h
+++ b/Applications/ApplicationsLib/LogogSetup.h
@@ -10,12 +10,12 @@
 #ifndef APPLICATIONSLIB_LOGOGSETUP_H_
 #define APPLICATIONSLIB_LOGOGSETUP_H_
 
-#include <logog/include/logog.hpp>
-
 #include <map>
 #include <memory>
 #include <string>
 
+#include <logog/include/logog.hpp>
+
 #include "BaseLib/LogogSimpleFormatter.h"
 
 namespace ApplicationsLib
@@ -69,14 +69,12 @@ public:
         };
 
 
-        //LOGOG_LEVEL_TYPE level_type;
+        LOGOG_LEVEL_TYPE level_type = LOGOG_LEVEL_ALL;
         if(foo.find(level) != foo.end())
-            setLevel(foo[level]);
+            level_type = foo[level];
         else
-        {
-            ERR("%s is not a valid log level! Aborting.", level.c_str());
-            std::abort();
-        }
+            WARN("'%s' is not a valid log level! 'all' is used instead.", level.c_str());
+        setLevel(level_type);
     }
 
 private:
diff --git a/Applications/ApplicationsLib/ProjectData.cpp b/Applications/ApplicationsLib/ProjectData.cpp
index 7d7c59c2eaf112ada970c225907d8e711c3b1684..e931ac9a298f75798a41d8b190bfd769f539f1d5 100644
--- a/Applications/ApplicationsLib/ProjectData.cpp
+++ b/Applications/ApplicationsLib/ProjectData.cpp
@@ -68,9 +68,8 @@ ProjectData::ProjectData(BaseLib::ConfigTree const& project_config,
 
     MeshLib::Mesh* const mesh = MeshLib::IO::readMeshFromFile(mesh_file);
     if (!mesh) {
-        ERR("Could not read mesh from \'%s\' file. No mesh added.",
+        OGS_FATAL("Could not read mesh from \'%s\' file. No mesh added.",
             mesh_file.c_str());
-        std::abort();
     }
     _mesh_vec.push_back(mesh);
 
@@ -193,8 +192,7 @@ void ProjectData::buildProcesses()
         }
         else
         {
-            ERR("Unknown process type: %s", type.c_str());
-            std::abort();
+            OGS_FATAL("Unknown process type: %s", type.c_str());
         }
     }
 
@@ -299,9 +297,8 @@ void ProjectData::parseParameters(BaseLib::ConfigTree const& parameters_config)
         }
         else
         {
-            ERR("Cannot construct property of given type \'%s\'.",
+            OGS_FATAL("Cannot construct property of given type \'%s\'.",
                 type.c_str());
-            std::abort();
         }
     }
 }
@@ -338,8 +335,7 @@ void ProjectData::parseTimeStepping(BaseLib::ConfigTree const& timestepping_conf
 
     if (!_time_loop)
     {
-        ERR("Initialization of time loop failed.");
-        std::abort();
+        OGS_FATAL("Initialization of time loop failed.");
     }
 }
 
@@ -391,13 +387,11 @@ createPiecewiseLinearInterpolation(BaseLib::ConfigTree const& config)
     auto values = config.getConfigParameter<std::vector<double>>("values");
     if (coords.empty() || values.empty())
     {
-        ERR("The given co-ordinates or values vector is empty.");
-        std::abort();
+        OGS_FATAL("The given co-ordinates or values vector is empty.");
     }
     if (coords.size() != values.size())
     {
-        ERR("The given co-ordinates and values vector sizes are different.");
-        std::abort();
+        OGS_FATAL("The given co-ordinates and values vector sizes are different.");
     }
 
     return std::unique_ptr<MathLib::PiecewiseLinearInterpolation>{
diff --git a/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h b/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h
index cc6e4f4c63211004c0776689f1e283d033ab26ff..275aeea03e4bbc4bb9b17de749901d9a541fd118 100644
--- a/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h
+++ b/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h
@@ -136,14 +136,12 @@ private:
                     *nonlinear_solver_newton, time_disc, *ode_newton };
             }
             else {
-                ERR("You are trying to solve a non-Newton-ready ODE with the"
+                OGS_FATAL("You are trying to solve a non-Newton-ready ODE with the"
                     " Newton-Raphson method. Aborting");
-                std::abort();
             }
         }
         else {
-            ERR("Encountered unknown nonlinear solver type. Aborting");
-            std::abort();
+            OGS_FATAL("Encountered unknown nonlinear solver type. Aborting");
         }
     }
 
@@ -242,8 +240,7 @@ createUncoupledProcessesTimeLoop(BaseLib::ConfigTree const& conf)
     } else if (type == "FixedTimeStepping") {
         timestepper = NumLib::FixedTimeStepping::newInstance(conf);
     } else {
-            ERR("Unknown timestepper type: `%s'.", type.c_str());
-            std::abort();
+            OGS_FATAL("Unknown timestepper type: `%s'.", type.c_str());
     }
 
     using TimeLoop = UncoupledProcessesTimeLoop<Matrix, Vector>;
diff --git a/Applications/CLI/ogs.cpp b/Applications/CLI/ogs.cpp
index 6fa28db83adf2fc61f4d83ba0323818396500dac..58164cfe6f09c98dc6326735a8886f380016a7a1 100644
--- a/Applications/CLI/ogs.cpp
+++ b/Applications/CLI/ogs.cpp
@@ -71,36 +71,41 @@ int main(int argc, char *argv[])
 
     cmd.parse(argc, argv);
 
-
     ApplicationsLib::LogogSetup logog_setup;
     logog_setup.setLevel(log_level_arg.getValue());
-    ApplicationsLib::LinearSolverLibrarySetup linear_solver_library_setup(
-        argc, argv);
 
+    try {
+        ApplicationsLib::LinearSolverLibrarySetup linear_solver_library_setup(
+            argc, argv);
 
-    auto project_config = BaseLib::makeConfigTree(
-        project_arg.getValue(), !nonfatal_arg.getValue(), "OpenGeoSysProject");
 
-    ProjectData project(*project_config, BaseLib::extractPath(project_arg.getValue()),
-                        outdir_arg.getValue());
+        auto project_config = BaseLib::makeConfigTree(
+            project_arg.getValue(), !nonfatal_arg.getValue(), "OpenGeoSysProject");
 
-    project_config.checkAndInvalidate();
+        ProjectData project(*project_config, BaseLib::extractPath(project_arg.getValue()),
+                            outdir_arg.getValue());
 
+        project_config.checkAndInvalidate();
 
-    // Create processes.
-    project.buildProcesses();
 
-    INFO("Initialize processes.");
-    for (auto p_it = project.processesBegin(); p_it != project.processesEnd(); ++p_it)
-    {
-        (*p_it)->initialize();
-    }
+        // Create processes.
+        project.buildProcesses();
 
+        INFO("Initialize processes.");
+        for (auto p_it = project.processesBegin(); p_it != project.processesEnd(); ++p_it)
+        {
+            (*p_it)->initialize();
+        }
 
-    INFO("Solve processes.");
 
-    auto& time_loop = project.getTimeLoop();
-    bool solver_succeeded = time_loop.loop(project);
+        INFO("Solve processes.");
 
-    return solver_succeeded ? EXIT_SUCCESS : EXIT_FAILURE;
+        auto& time_loop = project.getTimeLoop();
+        bool solver_succeeded = time_loop.loop(project);
+
+        return solver_succeeded ? EXIT_SUCCESS : EXIT_FAILURE;
+    } catch (std::exception& e) {
+        ERR(e.what());
+        return EXIT_FAILURE;
+    }
 }
diff --git a/Applications/Utils/MeshGeoTools/ComputeSurfaceNodeIDsInPolygonalRegion.cpp b/Applications/Utils/MeshGeoTools/ComputeSurfaceNodeIDsInPolygonalRegion.cpp
index 51348a0afdc46ebd864837865ce44eb58aacecca..75db24be21a13347bf068ec8e378a0b4f87f54f4 100644
--- a/Applications/Utils/MeshGeoTools/ComputeSurfaceNodeIDsInPolygonalRegion.cpp
+++ b/Applications/Utils/MeshGeoTools/ComputeSurfaceNodeIDsInPolygonalRegion.cpp
@@ -18,7 +18,7 @@
 
 #include "Applications/ApplicationsLib/LogogSetup.h"
 
-#include "BaseLib/StringTools.h"
+#include "BaseLib/Error.h"
 #include "BaseLib/FileTools.h"
 
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -39,13 +39,11 @@ void writeToFile(std::string const& id_area_fname, std::string const& csv_fname,
 {
     std::ofstream ids_and_area_out(id_area_fname);
     if (!ids_and_area_out) {
-        ERR("Unable to open the file \"%s\" - aborting.", id_area_fname.c_str());
-        std::abort();
+        OGS_FATAL("Unable to open the file \"%s\" - aborting.", id_area_fname.c_str());
     }
     std::ofstream csv_out(csv_fname);
     if (!csv_out) {
-        ERR("Unable to open the file \"%s\" - aborting.", csv_fname.c_str());
-        std::abort();
+        OGS_FATAL("Unable to open the file \"%s\" - aborting.", csv_fname.c_str());
     }
 
     ids_and_area_out << std::setprecision(20);
diff --git a/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp b/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp
index ec9dd4b9fc060f440cea4f362aeb902ebefad191..fc3a6ced702988246f3a4d0fdd3fb3a2cbb2f6a2 100644
--- a/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp
+++ b/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp
@@ -18,6 +18,7 @@
 
 #include "Applications/ApplicationsLib/LogogSetup.h"
 
+#include "BaseLib/Error.h"
 #include "BaseLib/FileTools.h"
 
 #include "MeshLib/IO/readMeshFromFile.h"
@@ -33,13 +34,11 @@ void writeToFile(std::string const& id_area_fname, std::string const& csv_fname,
 {
     std::ofstream ids_and_area_out(id_area_fname);
     if (!ids_and_area_out) {
-        ERR("Unable to open the file \"%s\" - aborting.", id_area_fname.c_str());
-        std::abort();
+        OGS_FATAL("Unable to open the file \"%s\" - aborting.", id_area_fname.c_str());
     }
     std::ofstream csv_out(csv_fname);
     if (!csv_out) {
-        ERR("Unable to open the file \"%s\" - aborting.", csv_fname.c_str());
-        std::abort();
+        OGS_FATAL("Unable to open the file \"%s\" - aborting.", csv_fname.c_str());
     }
 
     ids_and_area_out.precision(std::numeric_limits<double>::digits10);
diff --git a/BaseLib/ConfigTree.cpp b/BaseLib/ConfigTree.cpp
index 23b90e24d507169c3a2403568f18fa14ae57fc35..ac32d11f2a153bb4ccaa1f1562f9a54195d7becd 100644
--- a/BaseLib/ConfigTree.cpp
+++ b/BaseLib/ConfigTree.cpp
@@ -7,9 +7,12 @@
  *
  */
 
-#include <logog/include/logog.hpp>
 #include "ConfigTree.h"
 
+#include <logog/include/logog.hpp>
+
+#include "Error.h"
+
 // Explicitly instantiate the boost::property_tree::ptree which is a typedef to
 // the following basic_ptree.
 template class boost::property_tree::basic_ptree<std::string, std::string,
@@ -30,12 +33,10 @@ ConfigTree(PTree const& tree,
     : _tree(&tree), _filename(filename), _onerror(error_cb), _onwarning(warning_cb)
 {
     if (!_onerror) {
-        ERR("ConfigTree: No valid error handler provided.");
-        std::abort();
+        OGS_FATAL("ConfigTree: No valid error handler provided.");
     }
     if (!_onwarning) {
-        ERR("ConfigTree: No valid warning handler provided.");
-        std::abort();
+        OGS_FATAL("ConfigTree: No valid warning handler provided.");
     }
 }
 
@@ -193,7 +194,6 @@ void ConfigTree::ignoreConfigParameterAll(const std::string &param) const
 void ConfigTree::error(const std::string& message) const
 {
     _onerror(_filename, _path, message);
-    std::abort();
 }
 
 void ConfigTree::warning(const std::string& message) const
@@ -205,9 +205,8 @@ void ConfigTree::warning(const std::string& message) const
 void ConfigTree::onerror(const std::string& filename, const std::string& path,
                             const std::string& message)
 {
-    ERR("ConfigTree: In file `%s' at path <%s>: %s",
+    OGS_FATAL("ConfigTree: In file `%s' at path <%s>: %s",
         filename.c_str(), path.c_str(), message.c_str());
-    std::abort();
 }
 
 void ConfigTree::onwarning(const std::string& filename, const std::string& path,
diff --git a/BaseLib/ConfigTree.h b/BaseLib/ConfigTree.h
index 179b79ec7c4623201f9d8eb221b058141369a16b..74ccd116917e32425aefb5e2282790c2ff98641c 100644
--- a/BaseLib/ConfigTree.h
+++ b/BaseLib/ConfigTree.h
@@ -496,7 +496,7 @@ public:
     ~ConfigTree();
 
     //! Default error callback function
-    //! Will print an error message and call std::abort()
+    //! Will throw std::runtime_error
     static void onerror(std::string const& filename, std::string const& path,
                         std::string const& message);
 
@@ -532,11 +532,7 @@ private:
 
     /*! Called if an error occurs. Will call the error callback.
      *
-     * This method only acts as a helper method.
-     *
-     * This method finally calls <tt>std::abort()</tt>. In order to prevent that,
-     * a custom error callback that breaks out of the normal control flow---e.g., by throwing
-     * an exception---must be provided.
+     * This method only acts as a helper method and throws std::runtime_error.
      */
 #if defined(_MSC_VER) && _MSC_VER < 1900
     // 1900 == MSCV 14.0 == Visual Studio 2015
diff --git a/BaseLib/ConfigTreeUtil.cpp b/BaseLib/ConfigTreeUtil.cpp
index f85898d12f88c54c469d0f1207f4c81d97d70a23..fcb8af597263e27bef96ac55518dc69fb552be8a 100644
--- a/BaseLib/ConfigTreeUtil.cpp
+++ b/BaseLib/ConfigTreeUtil.cpp
@@ -7,10 +7,12 @@
  *
  */
 
+#include "ConfigTreeUtil.h"
+
 #include <boost/property_tree/xml_parser.hpp>
 #include <logog/include/logog.hpp>
 
-#include "ConfigTreeUtil.h"
+#include "Error.h"
 
 namespace BaseLib
 {
@@ -57,9 +59,8 @@ makeConfigTree(const std::string& filepath, const bool be_ruthless,
                  boost::property_tree::xml_parser::no_comments |
                  boost::property_tree::xml_parser::trim_whitespace);
     } catch (boost::property_tree::xml_parser_error e) {
-        ERR("Error while parsing XML file `%s' at line %lu: %s.",
+        OGS_FATAL("Error while parsing XML file `%s' at line %lu: %s.",
             e.filename().c_str(), e.line(), e.message().c_str());
-        std::abort();
     }
 
     DBUG("Project configuration from file \'%s\' read.", filepath.c_str());
@@ -67,9 +68,8 @@ makeConfigTree(const std::string& filepath, const bool be_ruthless,
     if (auto child = ptree.get_child_optional(toplevel_tag)) {
         return ConfigTreeTopLevel(filepath, be_ruthless, std::move(*child));
     } else {
-        ERR("Tag <%s> has not been found in file `%s'.",
+        OGS_FATAL("Tag <%s> has not been found in file `%s'.",
             toplevel_tag.c_str(), filepath.c_str());
-        std::abort();
     }
 }
 
diff --git a/BaseLib/Error.h b/BaseLib/Error.h
new file mode 100644
index 0000000000000000000000000000000000000000..f2894fd2066b21dcc079d053abce7c590bed2421
--- /dev/null
+++ b/BaseLib/Error.h
@@ -0,0 +1,24 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#ifndef BASELIB_ERROR_H
+#define BASELIB_ERROR_H
+
+#include <stdexcept>
+
+#include "StringTools.h"
+#include "FileTools.h"
+
+#define OGS_STR(x) #x
+#define OGS_STRINGIFY(x) OGS_STR(x)
+#define OGS_LOCATION " at " + BaseLib::extractBaseName(__FILE__) + ", line " OGS_STRINGIFY(__LINE__)
+#define OGS_FATAL(fmt, ...)\
+    throw std::runtime_error(BaseLib::format(fmt, ##__VA_ARGS__) + OGS_LOCATION);
+
+#endif //BASELIB_ERROR_H
diff --git a/BaseLib/StringTools.cpp b/BaseLib/StringTools.cpp
index 88a0e721863d478bc4dc5557776103c4b8625cc2..67694745465d727862e3e4932699eabb98dabe59 100644
--- a/BaseLib/StringTools.cpp
+++ b/BaseLib/StringTools.cpp
@@ -16,10 +16,11 @@
 
 #include <algorithm>
 #include <cctype>
+#include <cstdarg>
+#include <cstdio>
 #include <iomanip>
 
-#include "logog/include/logog.hpp"
-
+#include <logog/include/logog.hpp>
 #include <boost/algorithm/string/replace.hpp>
 
 namespace BaseLib
@@ -77,6 +78,23 @@ std::string const& tostring(std::string const& value)
     return value;
 }
 
+std::string format(const char* format_str, ... )
+{
+    va_list args;
+    va_start(args, format_str);
+    // get the number of chars to write
+    va_list args_tmp;
+    va_copy(args_tmp, args);
+    int char_length = std::vsnprintf(nullptr, 0, format_str, args_tmp);
+    va_end(args_tmp);
+    // allocate buffer and store formatted output there
+    std::vector<char> buffer(char_length + 1); // note +1 for null terminator
+    vsnprintf(buffer.data(), buffer.size(), format_str, args);
+    va_end(args);
+
+    return std::string(buffer.data());
+}
+
 } // end namespace BaseLib
 
 #ifdef MSVC
diff --git a/BaseLib/StringTools.h b/BaseLib/StringTools.h
index 8c3790269588ed753baed78fc174023ef75d6990..7ff25e9b5f48fdb48046772c26bc19263ae88e58 100644
--- a/BaseLib/StringTools.h
+++ b/BaseLib/StringTools.h
@@ -79,6 +79,9 @@ template<typename T> std::string tostring(T const& value)
 //! \overload
 std::string const& tostring(std::string const& value);
 
+//! returns printf-like formatted string
+std::string format(const char* format_string, ... );
+
 } // end namespace BaseLib
 
 #ifdef MSVC
diff --git a/BaseLib/uniqueInsert.h b/BaseLib/uniqueInsert.h
index 2db9220bfb2bd17413c94b60d40807a357358ecf..6211283edf5d835bbb73ba3401e9fc8c8c31bc45 100644
--- a/BaseLib/uniqueInsert.h
+++ b/BaseLib/uniqueInsert.h
@@ -17,7 +17,7 @@
 
 #include <algorithm>
 
-#include "StringTools.h"
+#include "Error.h"
 
 namespace BaseLib {
 
@@ -39,8 +39,7 @@ void insertIfKeyUniqueElseError(
 {
     auto const inserted = map.emplace(key, std::forward<Value>(value));
     if (!inserted.second) { // insertion failed, i.e., key already exists
-        ERR("%s Key `%s' already exists.", error_message.c_str(), tostring(key).c_str());
-        std::abort();
+        OGS_FATAL("%s Key `%s' already exists.", error_message.c_str(), tostring(key).c_str());
     }
 }
 
@@ -58,14 +57,12 @@ void insertIfKeyValueUniqueElseError(
 
     if (std::find_if(map.cbegin(), map.cend(), value_compare) != map.cend())
     {
-        ERR("%s Value `%s' already exists.", error_message.c_str(), tostring(value).c_str());
-        std::abort();
+        OGS_FATAL("%s Value `%s' already exists.", error_message.c_str(), tostring(value).c_str());
     }
 
     auto const inserted = map.emplace(key, std::forward<Value>(value));
     if (!inserted.second) { // insertion failed, i.e., key already exists
-        ERR("%s Key `%s' already exists.", error_message.c_str(), tostring(key).c_str());
-        std::abort();
+        OGS_FATAL("%s Key `%s' already exists.", error_message.c_str(), tostring(key).c_str());
     }
 }
 
@@ -81,8 +78,7 @@ getOrError(
 {
     auto it = map.find(key);
     if (it == map.end()) {
-        ERR("%s Key `%s' does not exist.", error_message.c_str(), tostring(key).c_str());
-        std::abort();
+        OGS_FATAL("%s Key `%s' does not exist.", error_message.c_str(), tostring(key).c_str());
     }
 
     return it->second;
@@ -96,8 +92,7 @@ getOrError(
 {
     auto it = map.find(key);
     if (it == map.end()) {
-        ERR("%s Key `%s' does not exist.", error_message.c_str(), tostring(key).c_str());
-        std::abort();
+        OGS_FATAL("%s Key `%s' does not exist.", error_message.c_str(), tostring(key).c_str());
     }
 
     return it->second;
diff --git a/GeoLib/AABB.h b/GeoLib/AABB.h
index 403364e7a0bc4abf81e3d058a4d8626346d73713..6643a1bb1befb2bbd1b5e405a64a29c6a7d6bbaf 100644
--- a/GeoLib/AABB.h
+++ b/GeoLib/AABB.h
@@ -27,6 +27,7 @@
 
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/Error.h"
 #include "MathLib/Point3d.h"
 #include "MathLib/MathTools.h"
 
@@ -88,8 +89,7 @@ public:
     {
         if (std::distance(first,last) <= 0)
         {
-            ERR("AABB::AABB(InputIterator first, InputIterator last): first > last");
-            std::abort();
+            OGS_FATAL("AABB::AABB(InputIterator first, InputIterator last): first > last");
         }
         init(*first);
         InputIterator it(first);
diff --git a/GeoLib/AnalyticalGeometry.cpp b/GeoLib/AnalyticalGeometry.cpp
index e7dcf9ab60d151431227fb8c56b9bf961ebe41de..13c6e3fdf3570252395ddaf4fd10ca4d1ac13fa7 100644
--- a/GeoLib/AnalyticalGeometry.cpp
+++ b/GeoLib/AnalyticalGeometry.cpp
@@ -20,6 +20,8 @@
 
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/StringTools.h"
+
 #include "Polyline.h"
 #include "PointVec.h"
 
@@ -427,11 +429,10 @@ std::vector<MathLib::Point3d> lineSegmentIntersect2d(
             std::stringstream err;
             err.precision(std::numeric_limits<double>::digits10);
             err << ab << " x " << cd;
-            ERR(
+            OGS_FATAL(
                 "The case of parallel line segments (%s) is not handled yet. "
                 "Aborting.",
                 err.str().c_str());
-            std::abort();
         }
 
         // check if d in (ab)
@@ -456,11 +457,10 @@ std::vector<MathLib::Point3d> lineSegmentIntersect2d(
             std::stringstream err;
             err.precision(std::numeric_limits<double>::digits10);
             err << ab << " x " << cd;
-            ERR(
+            OGS_FATAL(
                 "The case of parallel line segments (%s) "
                 "is not handled yet. Aborting.",
                 err.str().c_str());
-            std::abort();
         }
         return std::vector<MathLib::Point3d>();
     }
diff --git a/GeoLib/GeoType.cpp b/GeoLib/GeoType.cpp
index 4162b062e83fc1d7435301619533b462f675e9c8..d91b632db1a310d8afe5a6e45b1ee8499d5fd3ab 100644
--- a/GeoLib/GeoType.cpp
+++ b/GeoLib/GeoType.cpp
@@ -16,6 +16,8 @@
 
 #include <cstdlib>
 
+#include "BaseLib/Error.h"
+
 namespace GeoLib
 {
 
@@ -28,8 +30,9 @@ std::string convertGeoTypeToString (GEOTYPE geo_type)
     case GEOTYPE::SURFACE:  return "SURFACE";
     }
 
-    std::abort(); // Cannot happen, because switch covers all cases.
-                  // Used to silence compiler warning.
+    // Cannot happen, because switch covers all cases.
+    // Used to silence compiler warning.
+    OGS_FATAL("convertGeoTypeToString(): Given geo type is not supported");
 }
 
 } // end namespace GeoLib
diff --git a/GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.cpp b/GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.cpp
index 26414cbb821954ecb459d45999b1527d7637feac..e132bbf639d2a26fdcb5adc85736f01a1a6f9111 100644
--- a/GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.cpp
+++ b/GeoLib/IO/XmlIO/Boost/BoostXmlGmlInterface.cpp
@@ -12,11 +12,11 @@
  *
  */
 
+#include "BoostXmlGmlInterface.h"
+
 #include <boost/property_tree/xml_parser.hpp>
 #include <logog/include/logog.hpp>
 
-#include "BoostXmlGmlInterface.h"
-
 #include "BaseLib/ConfigTreeUtil.h"
 #include "BaseLib/uniqueInsert.h"
 #include "GeoLib/GEOObjects.h"
@@ -61,8 +61,7 @@ bool BoostXmlGmlInterface::readFile(const std::string &fname)
     auto geo_name = doc->getConfigParameter<std::string>("name");
     if (geo_name.empty())
     {
-        ERR("BoostXmlGmlInterface::readFile(): <name> tag is empty.");
-        std::abort();
+        OGS_FATAL("BoostXmlGmlInterface::readFile(): <name> tag is empty.");
     }
 
     //! \ogs_file_param{gml__points}
@@ -128,8 +127,7 @@ void BoostXmlGmlInterface::readPoints(BaseLib::ConfigTree const& pointsRoot,
         if (auto const p_name = pt.getConfigAttributeOptional<std::string>("name"))
         {
             if (p_name->empty()) {
-                ERR("Empty point name found in geometry file.");
-                std::abort();
+                OGS_FATAL("Empty point name found in geometry file.");
             }
 
             BaseLib::insertIfKeyUniqueElseError(pnt_names, *p_name, p_size,
@@ -160,8 +158,7 @@ void BoostXmlGmlInterface::readPolylines(
         if (auto const p_name = pl.getConfigAttributeOptional<std::string>("name"))
         {
             if (p_name->empty()) {
-                ERR("Empty polyline name found in geometry file.");
-                std::abort();
+                OGS_FATAL("Empty polyline name found in geometry file.");
             }
 
             BaseLib::insertIfKeyUniqueElseError(ply_names, *p_name, polylines.size()-1,
@@ -201,8 +198,7 @@ void BoostXmlGmlInterface::readSurfaces(
         if (auto const s_name = sfc.getConfigAttributeOptional<std::string>("name"))
         {
             if (s_name->empty()) {
-                ERR("Empty surface name found in geometry file.");
-                std::abort();
+                OGS_FATAL("Empty surface name found in geometry file.");
             }
 
             BaseLib::insertIfKeyUniqueElseError(sfc_names, *s_name, surfaces.size()-1,
diff --git a/GeoLib/Polyline.cpp b/GeoLib/Polyline.cpp
index 5f0df0f0482bf4ccd8151ad1fdc6e96e9f380a8e..d97abf615d5a1cd7d87dc87d685e51ba29cfd8c8 100644
--- a/GeoLib/Polyline.cpp
+++ b/GeoLib/Polyline.cpp
@@ -12,12 +12,11 @@
  *
  */
 
-// STL
-#include <algorithm>
+#include "Polyline.h"
 
+#include <algorithm>
 #include <logog/include/logog.hpp>
-
-#include "Polyline.h"
+#include "BaseLib/Error.h"
 #include "AnalyticalGeometry.h"
 #include "MathLib/GeometricBasics.h"
 
@@ -513,7 +512,7 @@ Polyline::SegmentIterator& Polyline::SegmentIterator::operator+=(
             static_cast<std::vector<GeoLib::Point>::size_type>(n);
     }
     if (_segment_number > _polyline->getNumberOfSegments())
-        std::abort();
+        OGS_FATAL("");
     return *this;
 }
 
@@ -536,7 +535,7 @@ Polyline::SegmentIterator& Polyline::SegmentIterator::operator-=(
             static_cast<std::vector<GeoLib::Point>::size_type>(-n);
     }
     if (_segment_number > _polyline->getNumberOfSegments())
-        std::abort();
+        OGS_FATAL("");
     return *this;
 }
 
diff --git a/GeoLib/SurfaceGrid.cpp b/GeoLib/SurfaceGrid.cpp
index 9eaf95ce71fdbe886b6f5eb9639e1ae91019f6ca..3bde55113fddb24e524c6f172af3f4e271a723d8 100644
--- a/GeoLib/SurfaceGrid.cpp
+++ b/GeoLib/SurfaceGrid.cpp
@@ -15,11 +15,13 @@
 
 #include <logog/include/logog.hpp>
 
-#include "Surface.h"
-#include "Triangle.h"
+#include "BaseLib/Error.h"
 
 #include "MathLib/Point3d.h"
 
+#include "Surface.h"
+#include "Triangle.h"
+
 namespace GeoLib {
 
 SurfaceGrid::SurfaceGrid(Surface const*const sfc) :
@@ -124,7 +126,7 @@ void SurfaceGrid::sortTrianglesInGridCells(Surface const*const sfc)
                 "grid.",
                 l, p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2]
             );
-            std::abort();
+            OGS_FATAL("");
         }
     }
 }
diff --git a/GeoLib/TemplateVec.h b/GeoLib/TemplateVec.h
index c10fc8a2c29174e3037feefc907230301eb1f359..6e9e98a7ddd814f8b1e21c9be518cfaddffe4131 100644
--- a/GeoLib/TemplateVec.h
+++ b/GeoLib/TemplateVec.h
@@ -25,6 +25,8 @@
 
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/Error.h"
+
 namespace GeoLib
 {
 /**
@@ -60,8 +62,7 @@ public:
     {
         if (_data_vec == nullptr)
         {
-            ERR("Constructor TemplateVec: vector of data elements is a nullptr.");
-            std::abort();
+            OGS_FATAL("Constructor TemplateVec: vector of data elements is a nullptr.");
         }
 
         if (!_name_id_map)
diff --git a/MaterialsLib/Adsorption/Reaction.cpp b/MaterialsLib/Adsorption/Reaction.cpp
index b3195ff639cb92e3c52372912eb8e428ade7c168..de84c5a596f59591831443ce66ac8a4b0eb4735d 100644
--- a/MaterialsLib/Adsorption/Reaction.cpp
+++ b/MaterialsLib/Adsorption/Reaction.cpp
@@ -9,6 +9,8 @@
 
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/StringTools.h"
+
 #include "Reaction.h"
 
 #include "Density100MPa.h"
@@ -58,8 +60,7 @@ newInstance(BaseLib::ConfigTree const& conf)
     else if (type == "CaOH2")
         return std::unique_ptr<Reaction>(new ReactionCaOH2(conf));
 
-    ERR("Unknown reactive system: %s.", type.c_str());
-    std::abort();
+    OGS_FATAL("Unknown reactive system: %s.", type.c_str());
 
     return nullptr;
 }
diff --git a/MaterialsLib/Adsorption/ReactionCaOH2.cpp b/MaterialsLib/Adsorption/ReactionCaOH2.cpp
index fc3df793dc66050ee82e8b938d88e9c1e5184689..89c3191e3e6af23cdfcda686795713530c17eb47 100644
--- a/MaterialsLib/Adsorption/ReactionCaOH2.cpp
+++ b/MaterialsLib/Adsorption/ReactionCaOH2.cpp
@@ -10,6 +10,7 @@
 #include "ReactionCaOH2.h"
 #include <cassert>
 #include <logog/include/logog.hpp>
+#include "BaseLib/Error.h"
 #include "MaterialsLib/PhysicalConstant.h"
 #include "Adsorption.h"
 
@@ -40,9 +41,7 @@ ReactionCaOH2::getEnthalpy(const double, const double, const double) const
 double
 ReactionCaOH2::getReactionRate(const double, const double, const double, const double) const
 {
-    ERR("get_reaction_rate do not call directly");
-    std::abort();
-    return -1.0;
+    OGS_FATAL("get_reaction_rate do not call directly");
 }
 
 
diff --git a/MaterialsLib/Adsorption/ReactionInert.h b/MaterialsLib/Adsorption/ReactionInert.h
index 7d53a28eec83381ada00e109182c709c8c673b15..48f4a03761e287138f90ce6dcdd06374dc13c513 100644
--- a/MaterialsLib/Adsorption/ReactionInert.h
+++ b/MaterialsLib/Adsorption/ReactionInert.h
@@ -10,6 +10,8 @@
 #ifndef MATERIALSLIB_ADSORPTION_REACTIONINERT_H
 #define MATERIALSLIB_ADSORPTION_REACTIONINERT_H
 
+#include "BaseLib/Error.h"
+
 #include "Reaction.h"
 
 namespace Adsorption
@@ -27,9 +29,7 @@ public:
     double getReactionRate(const double /*p_Ads*/, const double /*T_Ads*/, const double /*M_Ads*/,
                              const double /*loading*/) const override
     {
-        ERR("Method getReactionRate() should never be called directly");
-        std::abort();
-        return 0.0;
+        OGS_FATAL("Method getReactionRate() should never be called directly")
     }
 };
 
diff --git a/MaterialsLib/Adsorption/ReactionSinusoidal.h b/MaterialsLib/Adsorption/ReactionSinusoidal.h
index 5dc5b6db58d661bb094d42c409c8259cb73f66a4..833124c6e75d272f5cbfa83c32cc1a28237bc12c 100644
--- a/MaterialsLib/Adsorption/ReactionSinusoidal.h
+++ b/MaterialsLib/Adsorption/ReactionSinusoidal.h
@@ -14,6 +14,7 @@
 
 #include "Reaction.h"
 #include "BaseLib/ConfigTree.h"
+#include "BaseLib/StringTools.h"
 
 namespace Adsorption
 {
@@ -36,9 +37,7 @@ public:
     double getReactionRate(const double /*p_Ads*/, const double /*T_Ads*/, const double /*M_Ads*/,
                              const double /*loading*/) const override
     {
-        ERR("Method getReactionRate() should never be called directly");
-        std::abort();
-        return 0.0;
+        OGS_FATAL("Method getReactionRate() should never be called directly");
     }
 
 private:
diff --git a/MathLib/InterpolationAlgorithms/LinearIntervalInterpolation.h b/MathLib/InterpolationAlgorithms/LinearIntervalInterpolation.h
index 08c94b4fa85f8e05ccfa6986d949c00fceb0c051..bfd861295375fb257f89872c52f3c662b5903f7d 100644
--- a/MathLib/InterpolationAlgorithms/LinearIntervalInterpolation.h
+++ b/MathLib/InterpolationAlgorithms/LinearIntervalInterpolation.h
@@ -15,7 +15,7 @@
 #ifndef LINEARINTERVALINTERPOLATION_H_
 #define LINEARINTERVALINTERPOLATION_H_
 
-#include <stdexcept>
+#include "BaseLib/Error.h"
 
 namespace MathLib {
 
@@ -66,7 +66,7 @@ LinearIntervalInterpolation<NUMERIC_TYPE>::LinearIntervalInterpolation(NUMERIC_T
     _m (d-c), _n(0.0)
 {
     if (b == a) {
-        throw std::runtime_error("LinearIntervalInterpolation::LinearIntervalInterpolation: a == b, empty interval");
+        OGS_FATAL("LinearIntervalInterpolation::LinearIntervalInterpolation: a == b, empty interval");
     }
     _m /= (b-a);
     _n = c - _m * a;
diff --git a/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp b/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp
index ffa51c70ca6c469c96b36c294bc381b42742ad81..05e5206689db873319f2c76aced9d39325fe69b6 100644
--- a/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp
+++ b/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp
@@ -133,8 +133,7 @@ EigenLinearSolver::EigenLinearSolver(
         break;
     }
     case EigenOption::SolverType::INVALID:
-        ERR("Invalid Eigen linear solver type. Aborting.");
-        std::abort();
+        OGS_FATAL("Invalid Eigen linear solver type. Aborting.");
     }
 }
 
diff --git a/MathLib/LinAlg/Eigen/EigenTools.h b/MathLib/LinAlg/Eigen/EigenTools.h
index 9d533e70de4db171721a13bd83d0c785175296bc..7f18e8c959aa5a3182adae6e8191611fc2aed205 100644
--- a/MathLib/LinAlg/Eigen/EigenTools.h
+++ b/MathLib/LinAlg/Eigen/EigenTools.h
@@ -13,6 +13,7 @@
 #include <vector>
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/Error.h"
 #include "EigenMatrix.h" // for EigenMatrix::IndexType
 
 namespace MathLib
@@ -41,8 +42,7 @@ void applyKnownSolution(Eigen::MatrixXd &A, Eigen::VectorXd &b, Eigen::VectorXd
     (void) A; (void) b; (void) _vec_knownX_id; (void) _vec_knownX_x;
     (void) penalty_scaling;
 
-    ERR("Method not implemented."); // TODO implement
-    std::abort();
+    OGS_FATAL("Method not implemented."); // TODO implement
 }
 
 } // MathLib
diff --git a/MathLib/LinAlg/Lis/LisMatrix.cpp b/MathLib/LinAlg/Lis/LisMatrix.cpp
index 40d78d655e7add78905f3644e8e5be66136de2af..9b324f503aa76b875e60d8aa3d94dd0f35fdc370 100644
--- a/MathLib/LinAlg/Lis/LisMatrix.cpp
+++ b/MathLib/LinAlg/Lis/LisMatrix.cpp
@@ -19,6 +19,7 @@
 
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/Error.h"
 #include "LisVector.h"
 #include "LisCheck.h"
 
@@ -109,8 +110,7 @@ void LisMatrix::write(const std::string &filename) const
 {
     if (!_is_assembled)
     {
-        ERR("LisMatrix::write(): matrix not assembled.");
-        std::abort();
+        OGS_FATAL("LisMatrix::write(): matrix not assembled.");
     }
     lis_output_matrix(_AA, LIS_FMT_MM, const_cast<char*>(filename.c_str()));
 }
@@ -137,8 +137,7 @@ void LisMatrix::multiply(const LisVector &x, LisVector &y) const
 {
     if (!_is_assembled)
     {
-        ERR("LisMatrix::multiply(): matrix not assembled.");
-        std::abort();
+        OGS_FATAL("LisMatrix::multiply(): matrix not assembled.");
     }
     int ierr = lis_matvec(_AA, const_cast<LisVector*>(&x)->getRawVector(), y.getRawVector());
     checkLisError(ierr);
diff --git a/MathLib/Nonlinear/Root1D.h b/MathLib/Nonlinear/Root1D.h
index f015d66417ca1d8addfc54f3152e7f0254fbeda5..d5798d668af4eb1c21ed28c6ad987e8301f6222c 100644
--- a/MathLib/Nonlinear/Root1D.h
+++ b/MathLib/Nonlinear/Root1D.h
@@ -15,6 +15,7 @@
 #include <limits>
 #include <type_traits>
 #include <logog/include/logog.hpp>
+#include "BaseLib/Error.h"
 
 namespace MathLib
 {
@@ -62,9 +63,8 @@ public:
         } else if (detail::almost_zero(_fb)) {
             _a = _b;
         } else if (detail::same_sign(_fa, _fb)) {
-            ERR("Regula falsi cannot be done, because the function values"
+            OGS_FATAL("Regula falsi cannot be done, because the function values"
                 " at the interval ends have the same sign.");
-            std::abort();
         }
     }
 
diff --git a/MathLib/ODE/CVodeSolver.cpp b/MathLib/ODE/CVodeSolver.cpp
index e50c35159847482e19683c8bb36906de80a7db28..304f9e9026939f04f5c584a241ceff9695829d84 100644
--- a/MathLib/ODE/CVodeSolver.cpp
+++ b/MathLib/ODE/CVodeSolver.cpp
@@ -34,9 +34,8 @@ void check_error(std::string const& f_name, int const error_flag)
 {
     if (error_flag != CV_SUCCESS)
     {
-        ERR("CVodeSolver: %s failed with error flag %d.", f_name.c_str(),
-            error_flag);
-        std::abort();
+        OGS_FATAL("CVodeSolver: %s failed with error flag %d.", f_name.c_str(),
+            error_flag));
     }
 }
 
@@ -148,8 +147,7 @@ CVodeSolverImpl::CVodeSolverImpl(const BaseLib::ConfigTree& config,
         }
         else
         {
-            ERR("unknown linear multistep method: %s", param->c_str());
-            std::abort();
+            OGS_FATAL("unknown linear multistep method: %s", param->c_str()));
         }
     }
 
@@ -169,8 +167,7 @@ CVodeSolverImpl::CVodeSolverImpl(const BaseLib::ConfigTree& config,
         }
         else
         {
-            ERR("unknown nonlinear solver iteration: %s", param->c_str());
-            std::abort();
+            OGS_FATAL("unknown nonlinear solver iteration: %s", param->c_str()));
         }
     }
 
@@ -183,8 +180,7 @@ CVodeSolverImpl::CVodeSolverImpl(const BaseLib::ConfigTree& config,
 
     if (_cvode_mem == nullptr || _y == nullptr || _abstol == nullptr)
     {
-        ERR("couldn't allocate storage for CVode solver.");
-        std::abort();
+        OGS_FATAL("couldn't allocate storage for CVode solver."));
     }
 
     auto f_wrapped = [](const realtype t, const N_Vector y, N_Vector ydot,
diff --git a/MathLib/ODE/ODESolverBuilder.h b/MathLib/ODE/ODESolverBuilder.h
index 48ddb3a769cb4e4d7ac8d1cbf4e107796fa11aa9..9853faea4d1d50772597163e5aa7a4c50ae5782e 100644
--- a/MathLib/ODE/ODESolverBuilder.h
+++ b/MathLib/ODE/ODESolverBuilder.h
@@ -12,6 +12,7 @@
 
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/Error.h"
 #include "ODESolver.h"
 #include "ConcreteODESolver.h"
 
@@ -45,10 +46,9 @@ std::unique_ptr<ODESolver<NumEquations>> createODESolver(
 #endif
     (void)config;  // Unused parameter warning if no library is available.
 
-    ERR(
+    OGS_FATAL(
         "No ODE solver could be created. Maybe it is because you did not build"
         " OGS6 with support for any external ODE solver library.");
-    std::abort();
 }
 
 //! @}
diff --git a/MeshLib/IO/VtkIO/PVDFile.cpp b/MeshLib/IO/VtkIO/PVDFile.cpp
index 0dbc8167981cdce6b0c9307c02d0bbf7f0cd6a41..ff896e68817d80494b8fe9b3e6b77db5df9e0480 100644
--- a/MeshLib/IO/VtkIO/PVDFile.cpp
+++ b/MeshLib/IO/VtkIO/PVDFile.cpp
@@ -13,6 +13,7 @@
 #include <iomanip>
 #include <limits>
 #include <logog/include/logog.hpp>
+#include "BaseLib/Error.h"
 
 namespace MeshLib
 {
@@ -25,8 +26,7 @@ void PVDFile::addVTUFile(const std::string &vtu_fname, double timestep)
 
     std::ofstream fh(_pvd_filename.c_str());
     if (!fh) {
-        ERR("could not open file `%s'", _pvd_filename.c_str());
-        std::abort();
+        OGS_FATAL("could not open file `%s'", _pvd_filename.c_str());
     }
 
     fh << std::setprecision(std::numeric_limits<double>::digits10);
diff --git a/MeshLib/MeshSearch/MeshElementGrid.cpp b/MeshLib/MeshSearch/MeshElementGrid.cpp
index a9469a69fc97c4f15b3788aad016e1b9a8f95b08..a20fd2bed94286913ec736e3135b8a1546417a5c 100644
--- a/MeshLib/MeshSearch/MeshElementGrid.cpp
+++ b/MeshLib/MeshSearch/MeshElementGrid.cpp
@@ -114,9 +114,8 @@ void MeshElementGrid::sortElementsInGridCells(MeshLib::Mesh const& sfc_mesh)
 {
     for (auto const element : sfc_mesh.getElements()) {
         if (! sortElementInGridCells(*element)) {
-            ERR("Sorting element (id=%d) into mesh element grid.",
+            OGS_FATAL("Sorting element (id=%d) into mesh element grid.",
                 element->getID());
-            std::abort();
         }
     }
 }
diff --git a/MeshLib/MeshSubsets.h b/MeshLib/MeshSubsets.h
index 6fe6976d68bf9cc7f0b8bddaa69a0df16eda3843..29a3f97d738f368184211a0412a043ebfdc65786 100644
--- a/MeshLib/MeshSubsets.h
+++ b/MeshLib/MeshSubsets.h
@@ -21,6 +21,7 @@
 
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/Error.h"
 #include "MeshSubset.h"
 
 namespace MeshLib
@@ -48,8 +49,7 @@ public:
     {
         if (!areMeshSubsetMeshesUnique())
         {
-            ERR("Mesh ids of input mesh subsets are not unique.");
-            std::abort();
+            OGS_FATAL("Mesh ids of input mesh subsets are not unique.");
         }
 
         _n_total_items = std::accumulate(first, last, 0u,
diff --git a/NumLib/DOF/MeshComponentMap.cpp b/NumLib/DOF/MeshComponentMap.cpp
index 2cb4d31eb867b158c06beed16a6f20ebc460da83..765dfcf58aa543fca9f5532dc5ae68844e873ced 100644
--- a/NumLib/DOF/MeshComponentMap.cpp
+++ b/NumLib/DOF/MeshComponentMap.cpp
@@ -310,8 +310,7 @@ GlobalIndexType MeshComponentMap::getLocalIndex(
                                           _ghosts_indices.end(), -global_index);
     if (ghost_index_it == _ghosts_indices.end())
     {
-        ERR("index %d not found in ghost_indices", -global_index);
-        std::abort();
+        OGS_FATAL("index %d not found in ghost_indices", -global_index);
     }
 
     // Using std::distance on a std::vector is O(1). As long as _ghost_indices
diff --git a/NumLib/DOF/SimpleMatrixVectorProvider-impl.h b/NumLib/DOF/SimpleMatrixVectorProvider-impl.h
index f35879c2027f712282f32a8549cabd357a1da6b6..8e0672aec4236f1429d0299f4ce2633c33ed7642 100644
--- a/NumLib/DOF/SimpleMatrixVectorProvider-impl.h
+++ b/NumLib/DOF/SimpleMatrixVectorProvider-impl.h
@@ -10,6 +10,7 @@
 #include <cassert>
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/Error.h"
 #include "MathLib/LinAlg/BLAS.h"
 #include "MathLib/LinAlg/MatrixVectorTraits.h"
 #include "SimpleMatrixVectorProvider.h"
@@ -63,11 +64,10 @@ get_(std::size_t& id,
      Args&&... args)
 {
     if (id >= _next_id) {
-        ERR("An obviously uninitialized id argument has been passed."
+        OGS_FATAL("An obviously uninitialized id argument has been passed."
             " This might not be a serious error for the current implementation,"
             " but it might become one in the future."
             " Hence, I will abort now.");
-        std::abort();
     }
 
     if (do_search)
@@ -162,8 +162,7 @@ releaseMatrix(Matrix const& A)
 {
     auto it = _used_matrices.find(const_cast<Matrix*>(&A));
     if (it == _used_matrices.end()) {
-        ERR("The given matrix has not been found. Cannot release it. Aborting.");
-        std::abort();
+        OGS_FATAL("The given matrix has not been found. Cannot release it. Aborting.");
     } else {
         ::detail::transfer(_used_matrices, _unused_matrices, it);
     }
@@ -245,8 +244,7 @@ releaseVector(Vector const& x)
 {
     auto it = _used_vectors.find(const_cast<Vector*>(&x));
     if (it == _used_vectors.end()) {
-        ERR("The given vector has not been found. Cannot release it. Aborting.");
-        std::abort();
+        OGS_FATAL("The given vector has not been found. Cannot release it. Aborting.");
     } else {
         ::detail::transfer(_used_vectors, _unused_vectors, it);
     }
diff --git a/NumLib/ODESolver/NonlinearSolver-impl.h b/NumLib/ODESolver/NonlinearSolver-impl.h
index c2a641ddd330da57b4353aca6882dfefc80406e2..418bcea51048374e2c23a806c69ffa84827b8c93 100644
--- a/NumLib/ODESolver/NonlinearSolver-impl.h
+++ b/NumLib/ODESolver/NonlinearSolver-impl.h
@@ -13,6 +13,7 @@
 // #include <iostream>
 
 #include "BaseLib/ConfigTree.h"
+#include "BaseLib/Error.h"
 #include "MathLib/LinAlg/BLAS.h"
 #include "MathLib/LinAlg/VectorNorms.h"
 #include "NumLib/DOF/GlobalMatrixProviders.h"
@@ -283,7 +284,7 @@ createNonlinearSolver(MathLib::LinearSolver<Matrix, Vector>& linear_solver,
         return std::make_pair(std::unique_ptr<AbstractNLS>(
             new ConcreteNLS{linear_solver, tol, max_iter}), tag);
     }
-    std::abort();
+    OGS_FATAL("Unsupported nonlinear solver type");
 }
 
 
diff --git a/NumLib/ODESolver/TimeDiscretizationBuilder.h b/NumLib/ODESolver/TimeDiscretizationBuilder.h
index c3041c3a406892cb59bc0a43ba2163b43e846173..7f3ee05487b5760d0ae1446a3c04a7aff935edfb 100644
--- a/NumLib/ODESolver/TimeDiscretizationBuilder.h
+++ b/NumLib/ODESolver/TimeDiscretizationBuilder.h
@@ -44,8 +44,7 @@ createTimeDiscretization(BaseLib::ConfigTree const& config)
         using ConcreteTD = BackwardDifferentiationFormula<Vector>;
         return T(new ConcreteTD(order));
     } else {
-        ERR("Unrecognized time discretization type `%s'", type.c_str());
-        std::abort();
+        OGS_FATAL("Unrecognized time discretization type `%s'", type.c_str());
     }
 }
 
diff --git a/NumLib/TimeStepping/Algorithms/FixedTimeStepping.cpp b/NumLib/TimeStepping/Algorithms/FixedTimeStepping.cpp
index 1a9e082b7140ede18e191974325a90cda48868d2..a852a5d3c727f2a611b25838d614ab6cc56fefc5 100644
--- a/NumLib/TimeStepping/Algorithms/FixedTimeStepping.cpp
+++ b/NumLib/TimeStepping/Algorithms/FixedTimeStepping.cpp
@@ -20,6 +20,7 @@
 #include <logog/include/logog.hpp>
 
 #include "BaseLib/ConfigTree.h"
+#include "BaseLib/Error.h"
 
 namespace NumLib
 {
@@ -53,8 +54,7 @@ FixedTimeStepping::newInstance(BaseLib::ConfigTree const& config)
     //! \ogs_file_param{prj__time_stepping__FixedTimeStepping__timesteps__pair}
     auto const range = delta_ts.getConfigSubtreeList("pair");
     if (range.begin() == range.end()) {
-        ERR("no timesteps have been given");
-        std::abort();
+        OGS_FATAL("no timesteps have been given");
     }
     for (auto const pair : range)
     {
@@ -64,12 +64,10 @@ FixedTimeStepping::newInstance(BaseLib::ConfigTree const& config)
         delta_t           = pair.getConfigParameter<double>("delta_t");
 
         if (repeat == 0) {
-            ERR("<repeat> is zero.");
-            std::abort();
+            OGS_FATAL("<repeat> is zero.");
         }
         if (delta_t <= 0.0) {
-            ERR("timestep <delta_t> is <= 0.0.");
-            std::abort();
+            OGS_FATAL("timestep <delta_t> is <= 0.0.");
         }
 
         if (t_curr <= t_end) {
diff --git a/ProcessLib/CMakeLists.txt b/ProcessLib/CMakeLists.txt
index 280aac21594086dac29af104c64def5214621b96..06498e85745f399c6c14959c32f67b229580390d 100644
--- a/ProcessLib/CMakeLists.txt
+++ b/ProcessLib/CMakeLists.txt
@@ -9,6 +9,8 @@ APPEND_SOURCE_FILES(SOURCES GroundwaterFlow)
 add_subdirectory(TES)
 APPEND_SOURCE_FILES(SOURCES TES)
 
+APPEND_SOURCE_FILES(SOURCES Utils)
+
 add_library(ProcessLib ${SOURCES})
 
 target_link_libraries(ProcessLib
diff --git a/ProcessLib/GroundwaterFlow/GroundwaterFlowFEM.h b/ProcessLib/GroundwaterFlow/GroundwaterFlowFEM.h
index 7ce59f42a7bbe07aec0d361a7e0b834c63fbc60e..aa2d57f99cf2967f93304e4a91d65b7bc125b578 100644
--- a/ProcessLib/GroundwaterFlow/GroundwaterFlowFEM.h
+++ b/ProcessLib/GroundwaterFlow/GroundwaterFlowFEM.h
@@ -138,7 +138,7 @@ public:
             return _darcy_velocities[2];
         }
 
-        std::abort();
+        OGS_FATAL("");
     }
 
 private:
diff --git a/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.h b/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.h
index 192767dc646fda305c7c0837ddbe21a6b03c69c3..3bf2c24c8b4b68c04ead6243047c14e11680a408 100644
--- a/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.h
+++ b/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.h
@@ -53,14 +53,13 @@ public:
         if (dynamic_cast<NumLib::ForwardEuler<GlobalVector>*>(
                     &Base::getTimeDiscretization()) != nullptr)
         {
-            ERR("GroundwaterFlowProcess can not be solved with the ForwardEuler"
+            OGS_FATAL("GroundwaterFlowProcess can not be solved with the ForwardEuler"
                 " time discretization scheme. Aborting");
             // Because the M matrix is not assembled. Thus, the linearized system
             // would be singular. The same applies to CrankNicolson with theta = 0.0,
             // but this case is not checked here.
             // Anyway, the GroundwaterFlowProcess shall be transferred to a simpler
             // ODESystemTag in the future.
-            std::abort();
         }
     }
 
diff --git a/ProcessLib/InitialCondition.cpp b/ProcessLib/InitialCondition.cpp
index fe57541b02074ee1d366c4ce601a237368b1dbce..7554c135deba11c70a029b40b408a25abf0cdcd6 100644
--- a/ProcessLib/InitialCondition.cpp
+++ b/ProcessLib/InitialCondition.cpp
@@ -12,11 +12,13 @@
 #include <boost/optional.hpp>
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/ConfigTree.h"
+#include "BaseLib/Error.h"
+
 #include "MathLib/Point3d.h"
 #include "MeshLib/Elements/Element.h"
 #include "MeshLib/Mesh.h"
 
-#include "BaseLib/ConfigTree.h"
 
 namespace ProcessLib
 {
@@ -48,26 +50,23 @@ std::unique_ptr<InitialCondition> createMeshPropertyInitialCondition(
 
     if (!mesh.getProperties().hasPropertyVector(field_name))
     {
-        ERR("The required property %s does not exists in the mesh.",
+        OGS_FATAL("The required property %s does not exists in the mesh.",
             field_name.c_str());
-        std::abort();
     }
     auto const& property =
         mesh.getProperties().template getPropertyVector<double>(field_name);
     if (!property)
     {
-        ERR("The required property %s is not of the requested type.",
+        OGS_FATAL("The required property %s is not of the requested type.",
             field_name.c_str());
-        std::abort();
     }
 
     if (property->getNumberOfComponents() !=
         static_cast<std::size_t>(n_components))
     {
-        ERR("The required property %s has different number of components %d, "
+        OGS_FATAL("The required property %s has different number of components %d, "
             "expected %d.",
             field_name.c_str(), property->getNumberOfComponents(), n_components);
-        std::abort();
     }
     return std::unique_ptr<InitialCondition>(
         new MeshPropertyInitialCondition(*property));
diff --git a/ProcessLib/LocalAssemblerInterface.h b/ProcessLib/LocalAssemblerInterface.h
index 788ba9fbab39c4cb48b2e632a659e7c0e448b17a..338faa9376d3a32c70a3d5a8bd299b05496c3c37 100644
--- a/ProcessLib/LocalAssemblerInterface.h
+++ b/ProcessLib/LocalAssemblerInterface.h
@@ -33,20 +33,18 @@ public:
     virtual void assembleJacobian(double const /*t*/,
                                   std::vector<double> const& /*local_x*/)
     {
-        ERR(
+        OGS_FATAL(
             "assembleJacobian function is not implemented in the local "
             "assembler.");
-        std::abort();
     }
 
     virtual void addJacobianToGlobal(NumLib::LocalToGlobalIndexMap::
                                          RowColumnIndices const& /*indices*/,
                                      GlobalMatrix& /*Jac*/) const
     {
-        ERR(
+        OGS_FATAL(
             "addJacobianToGlobal function is not implemented in the local "
             "assembler.");
-        std::abort();
     }
 
     virtual void preTimestep(std::vector<double> const& /*local_x*/,
diff --git a/ProcessLib/Output.cpp b/ProcessLib/Output.cpp
index 047f0871af5c0e97467b2fcc83d94b0e55b537d0..76024cb4bdffedc54cd50e2e6f5978a26b5feefb 100644
--- a/ProcessLib/Output.cpp
+++ b/ProcessLib/Output.cpp
@@ -7,11 +7,11 @@
  *
  */
 
-#include<fstream>
 #include "Output.h"
 
-#include<cassert>
-#include<vector>
+#include <cassert>
+#include <fstream>
+#include <vector>
 
 #include <logog/include/logog.hpp>
 
@@ -69,9 +69,8 @@ newInstance(const BaseLib::ConfigTree &config, std::string const& output_directo
         }
 
         if (out->_repeats_each_steps.empty()) {
-            ERR("You have not given any pair (<repeat/>, <each_steps/>) that defines"
+            OGS_FATAL("You have not given any pair (<repeat/>, <each_steps/>) that defines"
                     " at which timesteps output shall be written. Aborting.");
-            std::abort();
         }
     }
     else
@@ -107,9 +106,8 @@ doOutputAlways(Process<GlobalSetup> const& process,
 {
     auto spd_it = _single_process_data.find(&process);
     if (spd_it == _single_process_data.end()) {
-        ERR("The given process is not contained in the output configuration."
+        OGS_FATAL("The given process is not contained in the output configuration."
             " Aborting.");
-        std::abort();
     }
     auto& spd = spd_it->second;
 
diff --git a/ProcessLib/Parameter.cpp b/ProcessLib/Parameter.cpp
index 188aeda773c462ebfcc25c5a636efdb752786f3d..0ad1e9e89eecfb9da4419d310a575a8fb2d8a3bb 100644
--- a/ProcessLib/Parameter.cpp
+++ b/ProcessLib/Parameter.cpp
@@ -12,6 +12,7 @@
 #include <boost/optional.hpp>
 #include <logog/include/logog.hpp>
 
+#include "BaseLib/Error.h"
 #include "MeshLib/Elements/Element.h"
 
 namespace ProcessLib
@@ -39,17 +40,15 @@ std::unique_ptr<ParameterBase> createMeshPropertyParameter(
 
     if (!mesh.getProperties().hasPropertyVector(field_name))
     {
-        ERR("The required property %s does not exists in the mesh.",
+        OGS_FATAL("The required property %s does not exists in the mesh.",
             field_name.c_str());
-        std::abort();
     }
     auto const& property =
         mesh.getProperties().template getPropertyVector<double>(field_name);
     if (!property)
     {
-        ERR("The required property %s is not of the requested type.",
+        OGS_FATAL("The required property %s is not of the requested type.",
             field_name.c_str());
-        std::abort();
     }
 
     return std::unique_ptr<ParameterBase>(
diff --git a/ProcessLib/Process.cpp b/ProcessLib/Process.cpp
index 7d2ef70d7ce092a71f2ddadf1690cb48b155cda6..d2d245c06a8b425321caf57f4675fe650b238901 100644
--- a/ProcessLib/Process.cpp
+++ b/ProcessLib/Process.cpp
@@ -28,11 +28,10 @@ ProcessVariable& findProcessVariable(
 
     if (variable == variables.end())
     {
-        ERR(
+        OGS_FATAL(
             "Could not find process variable '%s' in the provided variables "
             "list for config tag <%s>.",
             name.c_str(), tag.c_str());
-        std::abort();
     }
     DBUG("Found process variable \'%s\' for config tag <%s>.",
          variable->getName().c_str(), tag.c_str());
diff --git a/ProcessLib/Process.h b/ProcessLib/Process.h
index 728445c4d58391178f60f5f23f79f5717c94b086..f5844d18236c6967b7aa0db36354c048c62023f7 100644
--- a/ProcessLib/Process.h
+++ b/ProcessLib/Process.h
@@ -201,11 +201,10 @@ private:
         const double /*dx_dx*/, GlobalMatrix const& /*K*/,
         GlobalMatrix& /*Jac*/)
     {
-        ERR("The concrete implementation of this Process did not override the"
+        OGS_FATAL("The concrete implementation of this Process did not override the"
             " assembleJacobianConcreteProcess() method."
             " Hence, no analytical Jacobian is provided for this process"
             " and the Newton-Raphson method cannot be used to solve it.");
-        std::abort();
     }
 
     void constructDofTable()
@@ -385,11 +384,10 @@ Parameter<ParameterArgs...>& findParameter(
 
     if (parameter_it == parameters.end())
     {
-        ERR(
+        OGS_FATAL(
             "Could not find parameter '%s' in the provided parameters list for "
             "config tag <%s>.",
             name.c_str(), tag.c_str());
-        std::abort();
     }
     DBUG("Found parameter \'%s\'.", (*parameter_it)->name.c_str());
 
@@ -398,8 +396,7 @@ Parameter<ParameterArgs...>& findParameter(
         dynamic_cast<Parameter<ParameterArgs...>*>(parameter_it->get());
     if (!parameter)
     {
-        ERR("The read parameter is of incompatible type.");
-        std::abort();
+        OGS_FATAL("The read parameter is of incompatible type.");
     }
     return *parameter;
 }
diff --git a/ProcessLib/ProcessOutput.h b/ProcessLib/ProcessOutput.h
index db6e8164c1bc9e0aedf0e7cfc6020c9e8d1b430b..6bf1220aeef725e508de969d7634ce40309891bc 100644
--- a/ProcessLib/ProcessOutput.h
+++ b/ProcessLib/ProcessOutput.h
@@ -35,8 +35,7 @@ struct ProcessOutput final
         {
             if (output_variables.find(out_var) != output_variables.cend())
             {
-                ERR("output variable `%s' specified more than once.", out_var.c_str());
-                std::abort();
+                OGS_FATAL("output variable `%s' specified more than once.", out_var.c_str());
             }
 
             auto pred = [&out_var](ProcessVariable const& pv) {
@@ -50,9 +49,8 @@ struct ProcessOutput final
             if (pcs_var == process_variables.cend()
                 && !secondary_variables.variableExists(out_var))
             {
-                ERR("Output variable `%s' is neither a process variable nor a"
+                OGS_FATAL("Output variable `%s' is neither a process variable nor a"
                     " secondary variable", out_var.c_str());
-                std::abort();
             }
 
             DBUG("adding output variable `%s'", out_var.c_str());
diff --git a/ProcessLib/TES/TESReactionAdaptor.cpp b/ProcessLib/TES/TESReactionAdaptor.cpp
index 78199eb199e0bbaffdfa9cf44315e358ec5350c4..0524a4faa25e16a5447d1f586b6b127c4071c8a5 100644
--- a/ProcessLib/TES/TESReactionAdaptor.cpp
+++ b/ProcessLib/TES/TESReactionAdaptor.cpp
@@ -51,8 +51,7 @@ std::unique_ptr<TESFEMReactionAdaptor> TESFEMReactionAdaptor::newInstance(
             new TESFEMReactionAdaptorCaOH2(data));
     }
 
-    ERR("No suitable TESFEMReactionAdaptor found. Aborting.");
-    std::abort();
+    OGS_FATAL("No suitable TESFEMReactionAdaptor found. Aborting.");
     return std::unique_ptr<TESFEMReactionAdaptor>(nullptr);
 }
 
diff --git a/ProcessLib/Utils/CreateLocalAssemblers.h b/ProcessLib/Utils/CreateLocalAssemblers.h
index 081478cee2aea9f9a4d802e4585822c79501a66a..c5eaae8a7ff981741270e9c931017d7fef0d8066 100644
--- a/ProcessLib/Utils/CreateLocalAssemblers.h
+++ b/ProcessLib/Utils/CreateLocalAssemblers.h
@@ -115,8 +115,7 @@ void createLocalAssemblers(
                 std::forward<ExtraCtorArgs>(extra_ctor_args)...);
         break;
     default:
-        ERR("Meshes with dimension greater than three are not supported.");
-        std::abort();
+        OGS_FATAL("Meshes with dimension greater than three are not supported.");
     }
 }
 
diff --git a/ProcessLib/Utils/LocalDataInitializer.h b/ProcessLib/Utils/LocalDataInitializer.h
index 0172936204529718d967f800412afd9bc5e638c0..3f644c31556085363cf65783cded9febd83377f9 100644
--- a/ProcessLib/Utils/LocalDataInitializer.h
+++ b/ProcessLib/Utils/LocalDataInitializer.h
@@ -263,10 +263,9 @@ public:
                            mesh_item, num_local_dof, integration_order,
                            std::forward<ConstructorArgs>(args)...);
         } else {
-            ERR("You are trying to build a local assembler for an unknown mesh element type (%s)."
+            OGS_FATAL("You are trying to build a local assembler for an unknown mesh element type (%s)."
                 " Maybe you have disabled this mesh element type in your build configuration.",
                 type_idx.name());
-            std::abort();
         }
     }
 
diff --git a/Tests/GeoLib/TestGrid.cpp b/Tests/GeoLib/TestGrid.cpp
index ac1afece868fa20fc44d27dc1213994d87a9ff4f..6131275d0e9e6630499bc0d197cd2f08cc9705f6 100644
--- a/Tests/GeoLib/TestGrid.cpp
+++ b/Tests/GeoLib/TestGrid.cpp
@@ -23,7 +23,7 @@
 TEST(GeoLib, InsertZeroPointsInGrid)
 {
     std::vector<GeoLib::Point*> pnts;
-    ASSERT_DEATH(GeoLib::Grid<GeoLib::Point> grid(pnts.begin(), pnts.end()), "");
+    ASSERT_THROW(GeoLib::Grid<GeoLib::Point> grid(pnts.begin(), pnts.end()), std::runtime_error);
 }
 
 TEST(GeoLib, InsertOnePointInGrid)
diff --git a/Tests/GeoLib/TestPointVec.cpp b/Tests/GeoLib/TestPointVec.cpp
index 575b9e2927b17d1b9daacd6b27c86887a8dd24b6..96434a4a1b39d79a337cb5025c68e7969e07eca9 100644
--- a/Tests/GeoLib/TestPointVec.cpp
+++ b/Tests/GeoLib/TestPointVec.cpp
@@ -43,14 +43,14 @@ protected:
 // Testing nullptr input vector.
 TEST_F(PointVecTest, TestPointVecCtorNullptr)
 {
-    ASSERT_DEATH(GeoLib::PointVec(name, nullptr), "");
+    ASSERT_THROW(GeoLib::PointVec(name, nullptr), std::runtime_error);
 }
 
 // Testing empty input vector.
 TEST_F(PointVecTest, TestPointVecCtorEmpty)
 {
     auto ps_ptr = std::unique_ptr<VectorOfPoints>(new VectorOfPoints);
-    ASSERT_DEATH(GeoLib::PointVec(name, std::move(ps_ptr)), "");
+    ASSERT_THROW(GeoLib::PointVec(name, std::move(ps_ptr)), std::runtime_error);
 }
 
 // Testing input vector with single point.
diff --git a/Tests/MeshLib/MeshSubsets.cpp b/Tests/MeshLib/MeshSubsets.cpp
index 7fab7d33898d1cfe23bc351df30358f56ba359c9..cf37280b52ae0e60ce1e4f78a538c8d32ba8cd6e 100644
--- a/Tests/MeshLib/MeshSubsets.cpp
+++ b/Tests/MeshLib/MeshSubsets.cpp
@@ -33,8 +33,8 @@ TEST(MeshLibMeshSubsets, UniqueMeshIds)
     // EXPECT_NO_DEATH
     MeshSubsets(&mesh_subsets[0], &mesh_subsets[0] + 2);
 
-    EXPECT_DEATH(MeshSubsets(&mesh_subsets[1], &mesh_subsets[1] + 2), "");
-    EXPECT_DEATH(MeshSubsets(&mesh_subsets[0], &mesh_subsets[0] + 3), "");
+    EXPECT_THROW(MeshSubsets(&mesh_subsets[1], &mesh_subsets[1] + 2), std::runtime_error);
+    EXPECT_THROW(MeshSubsets(&mesh_subsets[0], &mesh_subsets[0] + 3), std::runtime_error);
 }
 
 
diff --git a/Tests/NumLib/TestExtrapolation.cpp b/Tests/NumLib/TestExtrapolation.cpp
index 769508122b7cadbb33b121b373899f9736fa13ad..baa5e97a413cbfddcd4e6b940c19296c3772f00a 100644
--- a/Tests/NumLib/TestExtrapolation.cpp
+++ b/Tests/NumLib/TestExtrapolation.cpp
@@ -125,7 +125,7 @@ public:
             return cache;
         }
 
-        std::abort();
+        OGS_FATAL("");
     }
 
     void interpolateNodalValuesToIntegrationPoints(