From 5852f11f73d3aa8cf85375619372df9e92e4a673 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Wed, 22 Apr 2020 18:27:12 +0200
Subject: [PATCH] Improve exception treatment

---
 src/main.cpp                | 16 +++++++++++-----
 src/utils/Exceptions.cpp    | 15 +++++++++------
 src/utils/Exceptions.hpp    | 23 ++++++++++++++++++++---
 src/utils/SignalManager.cpp |  6 ++++++
 src/utils/SignalManager.hpp |  1 +
 5 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/src/main.cpp b/src/main.cpp
index e48f74965..cd88b7ae1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -9,6 +9,7 @@
 #include <output/VTKWriter.hpp>
 
 #include <utils/Exceptions.hpp>
+#include <utils/SignalManager.hpp>
 #include <utils/Timer.hpp>
 
 #include <algebra/TinyMatrix.hpp>
@@ -410,11 +411,16 @@ main(int argc, char* argv[])
                 << "] Execution time: " << rang::style::bold << method_cost.second << rang::style::reset << '\n';
     }
   }
-  catch (const NormalError& e) {
-    // Each failing process must write
-    std::cerr.setstate(std::ios::goodbit);
-    std::cerr << e.what() << '\n';
-    return 1;
+  catch (const IExitError& e) {
+    if (SignalManager::pauseOnError()) {
+      std::rethrow_exception(std::current_exception());
+    } else {
+      // Each failing process must write
+      std::cerr.setstate(std::ios::goodbit);
+      std::cerr << e.what() << '\n';
+
+      return 1;
+    }
   }
 
   return 0;
diff --git a/src/utils/Exceptions.cpp b/src/utils/Exceptions.cpp
index 6c7603e83..85534848f 100644
--- a/src/utils/Exceptions.cpp
+++ b/src/utils/Exceptions.cpp
@@ -3,27 +3,30 @@
 #include <rang.hpp>
 
 #include <sstream>
+#include <string>
+
+RawError::RawError(std::string_view error_msg) : IExitError(std::string{error_msg}) {}
 
 NormalError::NormalError(std::string_view error_msg)
-  : std::runtime_error([&] {
+  : IExitError([&] {
       std::ostringstream os;
-      os << rang::style::bold << "Error:" << rang::style::reset << '\n' << error_msg << '\n';
+      os << rang::style::bold << "Error:" << rang::style::reset << ' ' << error_msg;
       return os.str();
     }())
 {}
 
 UnexpectedError::UnexpectedError(std::string_view error_msg)
-  : std::runtime_error([&] {
+  : IBacktraceError([&] {
       std::ostringstream os;
-      os << rang::fgB::red << "Unexpected error:" << rang::style::reset << '\n' << error_msg << '\n';
+      os << rang::fgB::red << "Unexpected error:" << rang::style::reset << ' ' << error_msg;
       return os.str();
     }())
 {}
 
 NotImplementedError::NotImplementedError(std::string_view error_msg)
-  : std::runtime_error([&] {
+  : IBacktraceError([&] {
       std::ostringstream os;
-      os << rang::fgB::yellow << "Not implemented yet:" << rang::style::reset << '\n' << error_msg << '\n';
+      os << rang::fgB::yellow << "Not implemented yet:" << rang::style::reset << ' ' << error_msg;
       return os.str();
     }())
 {}
diff --git a/src/utils/Exceptions.hpp b/src/utils/Exceptions.hpp
index 4256d02c8..1c0a56b4b 100644
--- a/src/utils/Exceptions.hpp
+++ b/src/utils/Exceptions.hpp
@@ -3,17 +3,34 @@
 
 #include <stdexcept>
 
-struct NormalError : public std::runtime_error
+struct IExitError : public std::runtime_error
+{
+  IExitError(std::string_view error_msg) : std::runtime_error(std::string{error_msg}){};
+  virtual ~IExitError() = default;
+};
+
+struct RawError : public IExitError
+{
+  RawError(std::string_view error_msg);
+};
+
+struct NormalError : public IExitError
 {
   NormalError(std::string_view error_msg);
 };
 
-struct UnexpectedError : public std::runtime_error
+struct IBacktraceError : public std::runtime_error
+{
+  IBacktraceError(const std::string& error_msg) : std::runtime_error(std::string{error_msg}){};
+  virtual ~IBacktraceError() = default;
+};
+
+struct UnexpectedError : IBacktraceError
 {
   UnexpectedError(std::string_view error_msg);
 };
 
-struct NotImplementedError : public std::runtime_error
+struct NotImplementedError : IBacktraceError
 {
   NotImplementedError(std::string_view error_msg);
 };
diff --git a/src/utils/SignalManager.cpp b/src/utils/SignalManager.cpp
index 2ff1499b4..45a6dd49d 100644
--- a/src/utils/SignalManager.cpp
+++ b/src/utils/SignalManager.cpp
@@ -15,6 +15,12 @@
 
 bool SignalManager::s_pause_on_error = false;
 
+bool
+SignalManager::pauseOnError()
+{
+  return s_pause_on_error;
+}
+
 void
 SignalManager::setPauseForDebug(const bool& pause_on_error)
 {
diff --git a/src/utils/SignalManager.hpp b/src/utils/SignalManager.hpp
index e1579f858..b64195e7e 100644
--- a/src/utils/SignalManager.hpp
+++ b/src/utils/SignalManager.hpp
@@ -12,6 +12,7 @@ struct SignalManager
   static void handler(int signal);
 
  public:
+  static bool pauseOnError();
   static void setPauseForDebug(const bool& pause_on_error);
   static void init(const bool& enable);
 };
-- 
GitLab