diff --git a/mex/sources/bytecode/BasicSymbolTable.cc b/mex/sources/bytecode/BasicSymbolTable.cc
index 820cc7ef91bba0afe3b2b954c714ace04bf799a8..e60ab96b9df0e4262a3c291abc8d2ab821882b9a 100644
--- a/mex/sources/bytecode/BasicSymbolTable.cc
+++ b/mex/sources/bytecode/BasicSymbolTable.cc
@@ -72,12 +72,12 @@ BasicSymbolTable::getName(SymbolType type, int tsid) const
         case SymbolType::parameter:
           return param_names.at(tsid);
         default:
-          mexErrMsgTxt(("Unsupported symbol type: " + to_string(static_cast<int>(type)) + "\n").c_str());
+          mexErrMsgTxt(("Unsupported symbol type: " + to_string(static_cast<int>(type))).c_str());
         }
     }
   catch (out_of_range &)
     {
-      mexErrMsgTxt(("Unknown symbol with ID " + to_string(tsid) + " and type " + to_string(static_cast<int>(type)) + "\n").c_str());
+      mexErrMsgTxt(("Unknown symbol with ID " + to_string(tsid) + " and type " + to_string(static_cast<int>(type))).c_str());
     }
   exit(EXIT_FAILURE); // Silence GCC warning
 }
@@ -91,7 +91,7 @@ BasicSymbolTable::getIDAndType(const string &name) const
     }
   catch (out_of_range &)
     {
-      mexErrMsgTxt(("Unknown symbol: " + name + "\n").c_str());
+      mexErrMsgTxt(("Unknown symbol: " + name).c_str());
     }
   exit(EXIT_FAILURE); // Silence GCC warning
 }
diff --git a/mex/sources/bytecode/ErrorHandling.hh b/mex/sources/bytecode/ErrorHandling.hh
index f6f7d94670fbee4ca4d3c197172f2e9909b95f61..eb651e120d3912874a42dcf6cdace4a27fd4b00d 100644
--- a/mex/sources/bytecode/ErrorHandling.hh
+++ b/mex/sources/bytecode/ErrorHandling.hh
@@ -46,115 +46,90 @@ constexpr int NO_ERROR_ON_EXIT = 0, ERROR_ON_EXIT = 1;
 
 using it_code_type = instructions_list_t::const_iterator;
 
-class GeneralExceptionHandling
+struct GeneralException
 {
-  string ErrorMsg;
-public:
-  GeneralExceptionHandling(string ErrorMsg_arg) : ErrorMsg{move(ErrorMsg_arg)}
-  {
-  };
-  inline string
-  GetErrorMsg()
-  {
-    return ErrorMsg;
-  }
-  inline void
-  completeErrorMsg(const string &ErrorMsg_arg)
-  {
-    ErrorMsg += ErrorMsg_arg;
-  }
+  const string message;
 };
 
-class FloatingPointExceptionHandling : public GeneralExceptionHandling
+struct FloatingPointException : public GeneralException
 {
-public:
-  FloatingPointExceptionHandling(const string &value) : GeneralExceptionHandling("Floating point error in bytecode: " + value)
+  FloatingPointException(const string &details) :
+    GeneralException {"Floating point error: " + details}
   {
   }
 };
 
-class LogExceptionHandling : public FloatingPointExceptionHandling
+struct LogException : public FloatingPointException
 {
-  double value;
-public:
-  LogExceptionHandling(double value_arg) : FloatingPointExceptionHandling("log(X)"),
-                                           value(value_arg)
+  LogException(double value) :
+    FloatingPointException { [=]
+    {
+      // We don’t use std::to_string(), because it uses fixed formatting
+      ostringstream s;
+      s << "log(X) with X=" << defaultfloat << value;
+      return s.str();
+    }() }
   {
-    // We don’t use std::to_string(), because it uses fixed formatting
-    ostringstream s;
-    s << " with X=" << defaultfloat << value << "\n";
-    completeErrorMsg(s.str());
   }
 };
 
-class Log10ExceptionHandling : public FloatingPointExceptionHandling
+struct Log10Exception : public FloatingPointException
 {
-  double value;
-public:
-  Log10ExceptionHandling(double value_arg) : FloatingPointExceptionHandling("log10(X)"),
-                                             value(value_arg)
+  Log10Exception(double value) :
+    FloatingPointException { [=]
+    {
+      // We don’t use std::to_string(), because it uses fixed formatting
+      ostringstream s;
+      s << "log10(X) with X=" << defaultfloat << value;
+      return s.str();
+    }() }
   {
-    // We don’t use std::to_string(), because it uses fixed formatting
-    ostringstream s;
-    s << " with X=" << defaultfloat << value << "\n";
-    completeErrorMsg(s.str());
   }
 };
 
-class DivideExceptionHandling : public FloatingPointExceptionHandling
+struct DivideException : public FloatingPointException
 {
-  double value1, value2;
-public:
-  DivideExceptionHandling(double value1_arg, double value2_arg) : FloatingPointExceptionHandling("a/X"),
-                                                                  value1(value1_arg),
-                                                                  value2(value2_arg)
+  DivideException(double divisor) :
+    FloatingPointException { [=]
+    {
+      // We don’t use std::to_string(), because it uses fixed formatting
+      ostringstream s;
+      s << "a/X with X=" << defaultfloat << divisor;
+      return s.str();
+    }() }
   {
-    // We don’t use std::to_string(), because it uses fixed formatting
-    ostringstream s;
-    s << " with X=" << defaultfloat << value2 << "\n";
-    completeErrorMsg(s.str());
   }
 };
 
-class PowExceptionHandling : public FloatingPointExceptionHandling
+struct PowException : public FloatingPointException
 {
-  double value1, value2;
-public:
-  PowExceptionHandling(double value1_arg, double value2_arg) : FloatingPointExceptionHandling("X^a"),
-                                                               value1(value1_arg),
-                                                               value2(value2_arg)
+  PowException(double base, double exponent) :
+    FloatingPointException { [=]
+    {
+      // We don’t use std::to_string(), because it uses fixed formatting
+      ostringstream s;
+      s << "X^a with X=" << defaultfloat << base;
+      if (fabs(base) <= 1e-10)
+        s << " and a=" << exponent;
+      return s.str();
+    }() }
   {
-    // We don’t use std::to_string(), because it uses fixed formatting
-    ostringstream s;
-    s << " with X=" << defaultfloat << value1;
-    if (fabs(value1) <= 1e-10)
-      s << " and a=" << value2;
-    s << "\n";
-    completeErrorMsg(s.str());
-  };
+  }
 };
 
-class UserExceptionHandling : public GeneralExceptionHandling
+struct UserException : public GeneralException
 {
-  double value;
-public:
-  UserExceptionHandling() : GeneralExceptionHandling("Fatal error in bytecode:")
+  UserException() : GeneralException {"User break"}
   {
-    completeErrorMsg(" User break\n");
-  };
+  }
 };
 
-class FatalExceptionHandling : public GeneralExceptionHandling
+struct FatalException : public GeneralException
 {
-public:
-  FatalExceptionHandling(const string &ErrorMsg_arg)
-    : GeneralExceptionHandling("Fatal error in bytecode:")
+  FatalException(const string &details) :
+    GeneralException {"Fatal error: " + details}
   {
-    completeErrorMsg(ErrorMsg_arg);
-  };
-  FatalExceptionHandling() : GeneralExceptionHandling("")
-  {
-  };
+  }
 };
 
 struct s_plan
@@ -318,7 +293,7 @@ protected:
       {
 #ifdef MATLAB_MEX_FILE
         if (utIsInterruptPending())
-          throw UserExceptionHandling();
+          throw UserException{};
 #endif
         switch ((*it_code)->op_code)
           {
@@ -344,9 +319,9 @@ protected:
                 equation_type = ExpressionType::FirstExodetDerivative;
                 break;
               default:
-                throw FatalExceptionHandling{" in print_expression, expression type "
-                                             + to_string(static_cast<int>(static_cast<FNUMEXPR_ *>(*it_code)->get_expression_type()))
-                                             + " not implemented yet\n"};
+                throw FatalException{"In print_expression, expression type "
+                                     + to_string(static_cast<int>(static_cast<FNUMEXPR_ *>(*it_code)->get_expression_type()))
+                                     + " not implemented yet"};
               }
             break;
           case Tags::FLDV:
@@ -363,7 +338,7 @@ protected:
                   Stack.emplace(symbol_table.getName(type, var) + lag_to_string(lag), 100, nullopt);
                   break;
                 default:
-                  throw FatalExceptionHandling{"FLDV: Unknown variable type\n"};
+                  throw FatalException{"FLDV: Unknown variable type"};
               }
             }
             break;
@@ -380,7 +355,7 @@ protected:
                   Stack.emplace(symbol_table.getName(type, var), 100, nullopt);
                   break;
                 default:
-                  throw FatalExceptionHandling{"FLDSV: Unknown variable type\n"};
+                  throw FatalException{"FLDSV: Unknown variable type"};
                 }
             }
             break;
@@ -397,7 +372,7 @@ protected:
                   Stack.emplace(symbol_table.getName(type, var), 100, nullopt);
                   break;
                 default:
-                  throw FatalExceptionHandling{"FLDVS: Unknown variable type\n"};
+                  throw FatalException{"FLDVS: Unknown variable type"};
                 }
             }
             break;
@@ -441,7 +416,7 @@ protected:
                   assign_lhs(symbol_table.getName(type, var) + lag_to_string(lag));
                   break;
                 default:
-                  throw FatalExceptionHandling{"FSTPV: Unknown variable type\n"};
+                  throw FatalException{"FSTPV: Unknown variable type"};
                 }
             }
             break;
@@ -458,7 +433,7 @@ protected:
                   assign_lhs(symbol_table.getName(type, var));
                   break;
                 default:
-                  throw FatalExceptionHandling{"FSTPSV: Unknown variable type\n"};
+                  throw FatalException{"FSTPSV: Unknown variable type"};
                 }
             }
             break;
@@ -506,7 +481,7 @@ protected:
                   case ExpressionType::FirstExodetDerivative:
                     return "jacob_exo_det";
                   default:
-                    throw FatalExceptionHandling{" unknown equation type " + to_string(static_cast<int>(equation_type)) + "\n"};
+                    throw FatalException{"Unknown equation type " + to_string(static_cast<int>(equation_type))};
                   }
               }() };
 
@@ -578,15 +553,15 @@ protected:
                     return "steady_state";
                   case UnaryOpcode::steadyStateParamDeriv:
                   case UnaryOpcode::steadyStateParam2ndDeriv:
-                    throw FatalExceptionHandling{"Unexpected derivative of steady_state operator"};
+                    throw FatalException{"Unexpected derivative of steady_state operator"};
                   case UnaryOpcode::expectation:
-                    throw FatalExceptionHandling{"Unexpected expectation operator"};
+                    throw FatalException{"Unexpected expectation operator"};
                   case UnaryOpcode::diff:
                     return "diff";
                   case UnaryOpcode::adl:
                     return "adl";
                   }
-                throw FatalExceptionHandling{"Unknown opcode"};
+                throw FatalException{"Unknown opcode"};
               }();
 
               /* Print argument. Enclose it with parentheses if:
@@ -659,7 +634,7 @@ protected:
                       case BinaryOpcode::max:
                         return 100;
                       }
-                    throw FatalExceptionHandling{"Unknown opcode"};
+                    throw FatalException{"Unknown opcode"};
                   }() };
 
                   /* Print left argument. If left argument has a lower
@@ -705,11 +680,11 @@ protected:
                     case BinaryOpcode::powerDeriv:
                     case BinaryOpcode::max:
                     case BinaryOpcode::min:
-                      throw FatalExceptionHandling{"Should not arrive here"};
+                      throw FatalException{"Should not arrive here"};
                     case BinaryOpcode::equal:
                       return " = ";
                     }
-                    throw FatalExceptionHandling{"Unknown opcode"};
+                    throw FatalException{"Unknown opcode"};
                   }();
 
                   /* Print right argument. Add parenthesis around right argument if:
@@ -752,7 +727,7 @@ protected:
                   case TrinaryOpcode::normpdf:
                     return "normpdf";
                   }
-                throw FatalExceptionHandling{"Unknown opcode"};
+                throw FatalException{"Unknown opcode"};
               }() };
 
               Stack.emplace(opname + "(" + arg1 + ", " + arg2 + ", " + arg3 + ")", 100, nullopt);
@@ -824,7 +799,7 @@ protected:
                 assign_lhs("[TEF(" + to_string(indx+1) + "), TEFD("  + to_string(indx+1) + "), TEFDD("  + to_string(indx+1) + ") ]");
                 break;
               default:
-                throw FatalExceptionHandling{"Unexpected external function call type"};
+                throw FatalException{"Unexpected external function call type"};
               }
             }
             break;
@@ -880,8 +855,8 @@ protected:
             go_on = false;
             break;
           default:
-            throw FatalExceptionHandling(" in print_expression, unknown opcode "
-                                         + to_string(static_cast<int>((*it_code)->op_code)) + "\n");
+            throw FatalException{"In print_expression, unknown opcode "
+                                 + to_string(static_cast<int>((*it_code)->op_code))};
           }
         it_code++;
       }
@@ -893,7 +868,7 @@ public:
   test_mxMalloc(void *z, int line, const string &file, const string &func, int amount)
   {
     if (!z && amount > 0)
-      throw FatalExceptionHandling(" mxMalloc: out of memory " + to_string(amount) + " bytes required at line " + to_string(line) + " in function " + func + " (file " + file);
+      throw FatalException{"mxMalloc: out of memory " + to_string(amount) + " bytes required at line " + to_string(line) + " in function " + func + " (file " + file};
   }
 };
 
diff --git a/mex/sources/bytecode/Evaluate.cc b/mex/sources/bytecode/Evaluate.cc
index f9a4cf1a78237ec358e723d631d9597933c041ed..db4eabf033dbf185e2b8abd6e0f92df5c376a57c 100644
--- a/mex/sources/bytecode/Evaluate.cc
+++ b/mex/sources/bytecode/Evaluate.cc
@@ -53,7 +53,7 @@ Evaluate::pow1(double a, double b)
       res1 = std::numeric_limits<double>::quiet_NaN();
       r = 0.0000000000000000000000001;
       if (print_error)
-        throw PowExceptionHandling(a, b);
+        throw PowException{a, b};
     }
   return r;
 }
@@ -67,7 +67,7 @@ Evaluate::divide(double a, double b)
       res1 = std::numeric_limits<double>::quiet_NaN();
       r = 1e70;
       if (print_error)
-        throw DivideExceptionHandling(a, b);
+        throw DivideException{b};
     }
   return r;
 }
@@ -81,7 +81,7 @@ Evaluate::log1(double a)
       res1 = std::numeric_limits<double>::quiet_NaN();
       r = -1e70;
       if (print_error)
-        throw LogExceptionHandling(a);
+        throw LogException{a};
     }
   return r;
 }
@@ -95,7 +95,7 @@ Evaluate::log10_1(double a)
       res1 = std::numeric_limits<double>::quiet_NaN();
       r = -1e70;
       if (print_error)
-        throw Log10ExceptionHandling(a);
+        throw Log10Exception{a};
     }
   return r;
 }
@@ -136,7 +136,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
     }
 #ifdef MATLAB_MEX_FILE
   if (utIsInterruptPending())
-    throw UserExceptionHandling();
+    throw UserException{};
 #endif
 
   while (go_on)
@@ -244,7 +244,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
               Stack.push(x[it_+lag+var*nb_row_x]);
               break;
             case SymbolType::exogenousDet:
-              mexErrMsgTxt("FLDV: exogenous deterministic not supported");
+              throw FatalException{"FLDV: exogenous deterministic not supported"};
               break;
             case SymbolType::modelLocalVariable:
 #ifdef DEBUG
@@ -288,7 +288,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
               Stack.push(x[var]);
               break;
             case SymbolType::exogenousDet:
-              mexErrMsgTxt("FLDSV: exogenous deterministic not supported");
+              throw FatalException{"FLDSV: exogenous deterministic not supported"};
               break;
             case SymbolType::modelLocalVariable:
 #ifdef DEBUG
@@ -326,7 +326,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
               Stack.push(x[var]);
               break;
             case SymbolType::exogenousDet:
-              mexErrMsgTxt("FLDVS: exogenous deterministic not supported");
+              throw FatalException{"FLDVS: exogenous deterministic not supported"};
               break;
             case SymbolType::modelLocalVariable:
 #ifdef DEBUG
@@ -442,7 +442,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
               Stack.pop();
               break;
             case SymbolType::exogenousDet:
-              mexErrMsgTxt("FSTPV: exogenous deterministic not supported");
+              throw FatalException{"FSTPV: exogenous deterministic not supported"};
               break;
             default:
               mexPrintf("FSTPV: Unknown variable type\n");
@@ -478,7 +478,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
               Stack.pop();
               break;
             case SymbolType::exogenousDet:
-              mexErrMsgTxt("FSTPSV: exogenous deterministic not supported");
+              throw FatalException{"FSTPSV: exogenous deterministic not supported"};
               break;
             default:
               mexPrintf("FSTPSV: Unknown variable type\n");
@@ -583,7 +583,8 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
           //store in the jacobian matrix
           rr = Stack.top();
           if (EQN_type != ExpressionType::FirstEndoDerivative)
-            throw FatalExceptionHandling(" in compute_block_time, impossible case " + to_string(static_cast<int>(EQN_type)) + " not implement in static jacobian\n");
+            throw FatalException{"In compute_block_time, impossible case " + to_string(static_cast<int>(EQN_type))
+                                 + " not implement in static jacobian"};
           eq = static_cast<FSTPG2_ *>(*it_code)->get_row();
           var = static_cast<FSTPG2_ *>(*it_code)->get_col();
 #ifdef DEBUG
@@ -656,7 +657,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
               jacob_exo_det[eq + size*pos_col] = rr;
               break;
             default:
-              throw FatalExceptionHandling(" in compute_block_time, variable " + to_string(static_cast<int>(EQN_type)) + " not used yet\n");
+              throw FatalException{"In compute_block_time, variable " + to_string(static_cast<int>(EQN_type)) + " not used yet"};
             }
 // #ifdef DEBUG
 //           tmp_out << "=>";
@@ -704,9 +705,9 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
                 {
                   tmp = divide(v1, v2);
                 }
-              catch (FloatingPointExceptionHandling &fpeh)
+              catch (FloatingPointException &fpeh)
                 {
-                  mexPrintf("%s      %s\n", fpeh.GetErrorMsg().c_str(), error_location(it_code_expr, it_code, steady_state, it_).c_str());
+                  mexPrintf("%s\n      %s\n", fpeh.message.c_str(), error_location(it_code_expr, it_code, steady_state, it_).c_str());
                   go_on = false;
                 }
               Stack.push(tmp);
@@ -758,9 +759,9 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
                 {
                   tmp = pow1(v1, v2);
                 }
-              catch (FloatingPointExceptionHandling &fpeh)
+              catch (FloatingPointException &fpeh)
                 {
-                  mexPrintf("%s      %s\n", fpeh.GetErrorMsg().c_str(), error_location(it_code_expr, it_code, steady_state, it_).c_str());
+                  mexPrintf("%s\n      %s\n", fpeh.message.c_str(), error_location(it_code_expr, it_code, steady_state, it_).c_str());
                   go_on = false;
                 }
               Stack.push(tmp);
@@ -787,9 +788,9 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
                         Stack.push(dxp);
                       }
                   }
-                catch (FloatingPointExceptionHandling &fpeh)
+                catch (FloatingPointException &fpeh)
                   {
-                    mexPrintf("%s      %s\n", fpeh.GetErrorMsg().c_str(), error_location(it_code_expr, it_code, steady_state, it_).c_str());
+                    mexPrintf("%s\n      %s\n", fpeh.message.c_str(), error_location(it_code_expr, it_code, steady_state, it_).c_str());
                     go_on = false;
                   }
               }
@@ -816,8 +817,8 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
             default:
               {
                 mexPrintf("Error\n");
-                throw FatalExceptionHandling(" in compute_block_time, unknown binary operator "
-                                             + to_string(static_cast<int>(op2)) + "\n");
+                throw FatalException{"In compute_block_time, unknown binary operator "
+                                     + to_string(static_cast<int>(op2))};
               }
             }
           break;
@@ -849,9 +850,9 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
                 {
                   tmp = log1(v1);
                 }
-              catch (FloatingPointExceptionHandling &fpeh)
+              catch (FloatingPointException &fpeh)
                 {
-                  mexPrintf("%s      %s\n", fpeh.GetErrorMsg().c_str(), error_location(it_code_expr, it_code, steady_state, it_).c_str());
+                  mexPrintf("%s\n      %s\n", fpeh.message.c_str(), error_location(it_code_expr, it_code, steady_state, it_).c_str());
                   go_on = false;
                 }
               Stack.push(tmp);
@@ -865,9 +866,9 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
                 {
                   tmp = log10_1(v1);
                 }
-              catch (FloatingPointExceptionHandling &fpeh)
+              catch (FloatingPointException &fpeh)
                 {
-                  mexPrintf("%s      %s\n", fpeh.GetErrorMsg().c_str(), error_location(it_code_expr, it_code, steady_state, it_).c_str());
+                  mexPrintf("%s\n      %s\n", fpeh.message.c_str(), error_location(it_code_expr, it_code, steady_state, it_).c_str());
                   go_on = false;
                 }
               Stack.push(tmp);
@@ -970,7 +971,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
             default:
               {
                 mexPrintf("Error\n");
-                throw FatalExceptionHandling(" in compute_block_time, unknown unary operator " + to_string(static_cast<int>(op1)) + "\n");
+                throw FatalException{"In compute_block_time, unknown unary operator " + to_string(static_cast<int>(op1))};
               }
             }
           break;
@@ -999,7 +1000,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
             default:
               {
                 mexPrintf("Error\n");
-                throw FatalExceptionHandling(" in compute_block_time, unknown trinary operator " + to_string(static_cast<int>(op3)) + "\n");
+                throw FatalException{"In compute_block_time, unknown trinary operator " + to_string(static_cast<int>(op3))};
               }
             }
           break;
@@ -1056,7 +1057,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
                       Stack.pop();
                     }
                   if (mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str()))
-                    throw FatalExceptionHandling(" external function: " + function_name + " not found");
+                    throw FatalException{"External function: " + function_name + " not found"};
 
                   double *rr = mxGetPr(output_arguments[0]);
                   Stack.push(*rr);
@@ -1110,7 +1111,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
 #endif
                   nb_input_arguments = 3;
                   if (mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str()))
-                    throw FatalExceptionHandling(" external function: " + function_name + " not found");
+                    throw FatalException{"External function: " + function_name + " not found"};
                   double *rr = mxGetPr(output_arguments[0]);
 #ifdef DEBUG
                   mexPrintf("*rr=%f\n", *rr);
@@ -1129,7 +1130,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
                       Stack.pop();
                     }
                   if (mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str()))
-                    throw FatalExceptionHandling(" external function: " + function_name + " not found");
+                    throw FatalException{"External function: " + function_name + " not found"};
                   int indx{fc->get_indx()};
                   double *FD1 = mxGetPr(output_arguments[0]);
                   size_t rows = mxGetN(output_arguments[0]);
@@ -1167,7 +1168,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
 #endif
                   nb_input_arguments = 3;
                   if (mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str()))
-                    throw FatalExceptionHandling(" external function: " + function_name + " not found");
+                    throw FatalException{"External function: " + function_name + " not found"};
                   double *rr = mxGetPr(output_arguments[0]);
                   Stack.push(*rr);
                 }
@@ -1183,7 +1184,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
                       Stack.pop();
                     }
                   if (mexCallMATLAB(nb_output_arguments, output_arguments, nb_input_arguments, input_arguments, function_name.c_str()))
-                    throw FatalExceptionHandling(" external function: " + function_name + " not found");
+                    throw FatalException{"External function: " + function_name + " not found"};
                   int indx{fc->get_indx()};
                   double *FD2 = mxGetPr(output_arguments[2]);
                   size_t rows = mxGetM(output_arguments[0]);
@@ -1320,7 +1321,7 @@ Evaluate::compute_block_time(int Per_u_, bool evaluate, bool no_derivative)
           it_code += static_cast<FJMP_ *>(*it_code)->get_pos() /*- 1 */;
           break;
         default:
-          throw FatalExceptionHandling(" in compute_block_time, unknown opcode " + to_string(static_cast<int>((*it_code)->op_code)) + "\n");
+          throw FatalException{"In compute_block_time, unknown opcode " + to_string(static_cast<int>((*it_code)->op_code))};
         }
       it_code++;
     }
@@ -1397,16 +1398,16 @@ Evaluate::solve_simple_one_periods()
         {
           y[Block_Contain[0].Variable + Per_y_] += -slowc *divide(rr, g1[0]);
         }
-      catch (FloatingPointExceptionHandling &fpeh)
+      catch (FloatingPointException &fpeh)
         {
-          mexPrintf("%s      \n", fpeh.GetErrorMsg().c_str());
+          mexPrintf("%s\n      \n", fpeh.message.c_str());
           mexPrintf("      Singularity in block %d", block_num+1);
         }
       iter++;
     }
   if (!cvg)
-    throw FatalExceptionHandling(" in Solve Forward simple, convergence not achieved in block "
-                                 + to_string(block_num+1) + ", after " + to_string(iter) + " iterations\n");
+    throw FatalException{"In Solve Forward simple, convergence not achieved in block "
+                         + to_string(block_num+1) + ", after " + to_string(iter) + " iterations"};
 }
 
 void
diff --git a/mex/sources/bytecode/Interpreter.cc b/mex/sources/bytecode/Interpreter.cc
index d9b80e4614487a65633b0c902cc0c0ec09ef73e6..8e2f866d4cbf27ecef9f905772ed74006b47a5be 100644
--- a/mex/sources/bytecode/Interpreter.cc
+++ b/mex/sources/bytecode/Interpreter.cc
@@ -297,7 +297,7 @@ Interpreter::evaluate_a_block(bool initialization)
       mxFree(r);
       break;
     case BlockSimulationType::unknown:
-      throw FatalExceptionHandling("UNKNOWN block simulation type: impossible case");
+      throw FatalException{"UNKNOWN block simulation type: impossible case"};
     }
 }
 
@@ -467,9 +467,9 @@ Interpreter::simulate_a_block(const vector_table_conditional_local_type &vector_
                 }
             }
           if (!cvg)
-            throw FatalExceptionHandling(" in Solve two boundaries, convergence not achieved in block "
-                                         + to_string(block_num+1) + ", after "
-                                         + to_string(iter) + " iterations\n");
+            throw FatalException{"In Solve two boundaries, convergence not achieved in block "
+                                 + to_string(block_num+1) + ", after "
+                                 + to_string(iter) + " iterations"};
         }
       else
         {
@@ -502,7 +502,7 @@ Interpreter::simulate_a_block(const vector_table_conditional_local_type &vector_
       End_Solver();
       break;
     default:
-      throw FatalExceptionHandling(" in simulate_a_block, Unknown type = " + to_string(static_cast<int>(type)) + "\n");
+      throw FatalException{"In simulate_a_block, Unknown type = " + to_string(static_cast<int>(type))};
       return ERROR_ON_EXIT;
     }
   return NO_ERROR_ON_EXIT;
@@ -562,11 +562,11 @@ Interpreter::ReadCodeFile(string file_name, CodeLoad &code)
   code_liste = code.get_op_code(file_name);
   EQN_block_number = code.get_block_number();
   if (!code_liste.size())
-    throw FatalExceptionHandling(" in compute_blocks, " + file_name + ".cod cannot be opened\n");
+    throw FatalException{"In compute_blocks, " + file_name + ".cod cannot be opened"};
   if (block >= code.get_block_number())
-    throw FatalExceptionHandling(" in compute_blocks, input argument block = " + to_string(block+1)
-                                 + " is greater than the number of blocks in the model ("
-                                 + to_string(code.get_block_number()) + " see M_.block_structure_stat.block)\n");
+    throw FatalException{"In compute_blocks, input argument block = " + to_string(block+1)
+                         + " is greater than the number of blocks in the model ("
+                         + to_string(code.get_block_number()) + " see M_.block_structure_stat.block)"};
 }
 
 void
@@ -578,23 +578,23 @@ Interpreter::check_for_controlled_exo_validity(FBEGINBLOCK_ *fb, const vector<s_
     {
       if (find(endogenous.begin(), endogenous.end(), it.exo_num) != endogenous.end()
           && find(exogenous.begin(), exogenous.end(), it.var_num) == exogenous.end())
-        throw FatalExceptionHandling("\n the conditional forecast involving as constrained variable "
-                                     + symbol_table.getName(SymbolType::endogenous, it.exo_num)
-                                     + " and as endogenized exogenous " + symbol_table.getName(SymbolType::exogenous, it.var_num)
-                                     + " that do not appear in block=" + to_string(Block_Count+1)
-                                     + ")\n You should not use block in model options\n");
+        throw FatalException{"\nThe conditional forecast involving as constrained variable "
+                             + symbol_table.getName(SymbolType::endogenous, it.exo_num)
+                             + " and as endogenized exogenous " + symbol_table.getName(SymbolType::exogenous, it.var_num)
+                             + " that do not appear in block=" + to_string(Block_Count+1)
+                             + ")\nYou should not use block in model options"};
       else if (find(endogenous.begin(), endogenous.end(), it.exo_num) != endogenous.end()
                && find(exogenous.begin(), exogenous.end(), it.var_num) != exogenous.end()
                && (fb->get_type() == BlockSimulationType::evaluateForward
                    || fb->get_type() == BlockSimulationType::evaluateBackward))
-        throw FatalExceptionHandling("\n the conditional forecast cannot be implemented for the block="
-                                     + to_string(Block_Count+1) + ") that has to be evaluated instead to be solved\n You should not use block in model options\n");
+        throw FatalException{"\nThe conditional forecast cannot be implemented for the block="
+                             + to_string(Block_Count+1) + ") that has to be evaluated instead to be solved\nYou should not use block in model options"};
       else if (find(previous_block_exogenous.begin(), previous_block_exogenous.end(), it.var_num)
                != previous_block_exogenous.end())
-        throw FatalExceptionHandling("\n the conditional forecast involves in the block "
-                                     + to_string(Block_Count+1) + " the endogenized exogenous "
-                                     + symbol_table.getName(SymbolType::exogenous, it.var_num)
-                                     + " that appear also in a previous block\n You should not use block in model options\n");
+        throw FatalException{"\nThe conditional forecast involves in the block "
+                             + to_string(Block_Count+1) + " the endogenized exogenous "
+                             + symbol_table.getName(SymbolType::exogenous, it.var_num)
+                             + " that appear also in a previous block\nYou should not use block in model options"};
     }
   for (auto it : exogenous)
     previous_block_exogenous.push_back(it);
@@ -762,9 +762,9 @@ Interpreter::MainLoop(const string &bin_basename, const CodeLoad &code, bool eva
             it_code++;
           break;
         default:
-          throw FatalExceptionHandling(" in compute_blocks, unknown command "
-                                       + to_string(static_cast<int>((*it_code)->op_code)) + " (block="
-                                       + to_string(Block_Count) + ")\n");
+          throw FatalException{"In compute_blocks, unknown command "
+                               + to_string(static_cast<int>((*it_code)->op_code)) + " (block="
+                               + to_string(Block_Count) + ")"};
         }
     }
   max_res = max_res_local;
diff --git a/mex/sources/bytecode/SparseMatrix.cc b/mex/sources/bytecode/SparseMatrix.cc
index 269362b38fa3f36b30895b385095e0d63d8c053c..20b60d7fecebe73e36e5bd97296f193a48a80e88 100644
--- a/mex/sources/bytecode/SparseMatrix.cc
+++ b/mex/sources/bytecode/SparseMatrix.cc
@@ -296,10 +296,10 @@ dynSparseMatrix::Read_SparseMatrix(const string &file_name, int Size, int period
         {
           ostringstream tmp;
           if (steady_state)
-            tmp << " in Read_SparseMatrix, " << file_name << "/model/bytecode/static.bin cannot be opened\n";
+            tmp << "In Read_SparseMatrix, " << file_name << "/model/bytecode/static.bin cannot be opened";
           else
-            tmp << " in Read_SparseMatrix, " << file_name << "/model/bytecode/dynamic.bin cannot be opened\n";
-          throw FatalExceptionHandling(tmp.str());
+            tmp << "In Read_SparseMatrix, " << file_name << "/model/bytecode/dynamic.bin cannot be opened";
+          throw FatalException{tmp.str()};
         }
     }
   IM_i.clear();
@@ -335,7 +335,7 @@ dynSparseMatrix::Read_SparseMatrix(const string &file_name, int Size, int period
             IM_i[{ Size*(periods+y_kmax), 0, j }] = j;
         }
       else
-        mexErrMsgTxt("Invalid value for solve_algo or stack_solve_algo");
+        throw FatalException{"Invalid value for solve_algo or stack_solve_algo"};
     }
   else
     {
@@ -366,7 +366,7 @@ dynSparseMatrix::Read_SparseMatrix(const string &file_name, int Size, int period
             }
         }
       else
-        mexErrMsgTxt("Invalid value for solve_algo or stack_solve_algo");
+        throw FatalException{"Invalid value for solve_algo or stack_solve_algo"};
     }
   index_vara = static_cast<int *>(mxMalloc(Size*(periods+y_kmin+y_kmax)*sizeof(int)));
   test_mxMalloc(index_vara, __LINE__, __FILE__, __func__, Size*(periods+y_kmin+y_kmax)*sizeof(int));
@@ -476,19 +476,19 @@ dynSparseMatrix::Init_Matlab_Sparse_Simple(int Size, const map<tuple<int, int, i
 {
   double *b = mxGetPr(b_m);
   if (!b)
-    throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, can't retrieve b vector\n");
+    throw FatalException{"In Init_Matlab_Sparse_Simple, can't retrieve b vector"};
   double *x0 = mxGetPr(x0_m);
   if (!x0)
-    throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, can't retrieve x0 vector\n");
+    throw FatalException{"In Init_Matlab_Sparse_Simple, can't retrieve x0 vector"};
   mwIndex *Ai = mxGetIr(A_m);
   if (!Ai)
-    throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, can't allocate Ai index vector\n");
+    throw FatalException{"In Init_Matlab_Sparse_Simple, can't allocate Ai index vector"};
   mwIndex *Aj = mxGetJc(A_m);
   if (!Aj)
-    throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, can't allocate Aj index vector\n");
+    throw FatalException{"In Init_Matlab_Sparse_Simple, can't allocate Aj index vector"};
   double *A = mxGetPr(A_m);
   if (!A)
-    throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, can't retrieve A matrix\n");
+    throw FatalException{"In Init_Matlab_Sparse_Simple, can't retrieve A matrix"};
 
   for (int i = 0; i < y_size*(periods+y_kmin); i++)
     ya[i] = y[i];
@@ -521,28 +521,28 @@ dynSparseMatrix::Init_Matlab_Sparse_Simple(int Size, const map<tuple<int, int, i
         }
 #ifdef DEBUG
       if (index < 0 || index >= u_count_alloc || index > Size + Size*Size)
-        throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, index (" + to_string(index)
-                                     + ") out of range for u vector max = "
-                                     + to_string(Size+Size*Size)
-                                     + " allocated = " + to_string(u_count_alloc) + "\n");
+        throw FatalException{"In Init_Matlab_Sparse_Simple, index (" + to_string(index)
+                             + ") out of range for u vector max = "
+                             + to_string(Size+Size*Size)
+                             + " allocated = " + to_string(u_count_alloc)};
       if (NZE >= max_nze)
-        throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, exceeds the capacity of A_m sparse matrix\n");
+        throw FatalException{"In Init_Matlab_Sparse_Simple, exceeds the capacity of A_m sparse matrix"};
 #endif
       A[NZE] = u[index];
       Ai[NZE] = eq;
       NZE++;
 #ifdef DEBUG
       if (eq < 0 || eq >= Size)
-        throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, index (" + to_string(eq)
-                                     + ") out of range for b vector\n");
+        throw FatalException{"In Init_Matlab_Sparse_Simple, index (" + to_string(eq)
+                             + ") out of range for b vector"};
       if (var < 0 || var >= Size)
-        throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, index (" + to_string(var)
-                                     + ") out of range for index_vara vector\n");
+        throw FatalException{"In Init_Matlab_Sparse_Simple, index (" + to_string(var)
+                             + ") out of range for index_vara vector"};
       if (index_vara[var] < 0 || index_vara[var] >= y_size)
-        throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, index ("
-                                     + to_string(index_vara[var])
-                                     + ") out of range for y vector max=" + to_string(y_size)
-                                     +" (0)\n");
+        throw FatalException{"In Init_Matlab_Sparse_Simple, index ("
+                             + to_string(index_vara[var])
+                             + ") out of range for y vector max=" + to_string(y_size)
+                             +" (0)"};
 #endif
     }
   Aj[Size] = NZE;
@@ -554,23 +554,23 @@ dynSparseMatrix::Init_UMFPACK_Sparse_Simple(int Size, const map<tuple<int, int,
   *b = static_cast<double *>(mxMalloc(Size * sizeof(double)));
   test_mxMalloc(*b, __LINE__, __FILE__, __func__, Size * sizeof(double));
   if (!(*b))
-    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, can't retrieve b vector\n");
+    throw FatalException{"In Init_UMFPACK_Sparse, can't retrieve b vector"};
   double *x0 = mxGetPr(x0_m);
   if (!x0)
-    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse_Simple, can't retrieve x0 vector\n");
+    throw FatalException{"In Init_UMFPACK_Sparse_Simple, can't retrieve x0 vector"};
   *Ap = static_cast<SuiteSparse_long *>(mxMalloc((Size+1) * sizeof(SuiteSparse_long)));
   test_mxMalloc(*Ap, __LINE__, __FILE__, __func__, (Size+1) * sizeof(SuiteSparse_long));
   if (!(*Ap))
-    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, can't allocate Ap index vector\n");
+    throw FatalException{"In Init_UMFPACK_Sparse, can't allocate Ap index vector"};
   size_t prior_nz = IM.size();
   *Ai = static_cast<SuiteSparse_long *>(mxMalloc(prior_nz * sizeof(SuiteSparse_long)));
   test_mxMalloc(*Ai, __LINE__, __FILE__, __func__, prior_nz * sizeof(SuiteSparse_long));
   if (!(*Ai))
-    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, can't allocate Ai index vector\n");
+    throw FatalException{"In Init_UMFPACK_Sparse, can't allocate Ai index vector"};
   *Ax = static_cast<double *>(mxMalloc(prior_nz * sizeof(double)));
   test_mxMalloc(*Ax, __LINE__, __FILE__, __func__, prior_nz * sizeof(double));
   if (!(*Ax))
-    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, can't retrieve Ax matrix\n");
+    throw FatalException{"In Init_UMFPACK_Sparse, can't retrieve Ax matrix"};
   for (int i = 0; i < Size; i++)
     {
       int eq = index_vara[i];
@@ -605,28 +605,28 @@ dynSparseMatrix::Init_UMFPACK_Sparse_Simple(int Size, const map<tuple<int, int,
         }
 #ifdef DEBUG
       if (index < 0 || index >= u_count_alloc || index > Size + Size*Size)
-        throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, index (" + to_string(index)
-                                     + ") out of range for u vector max = "
-                                     + to_string(Size+Size*Size)
-                                     + " allocated = " + to_string(u_count_alloc) + "\n");
+        throw FatalException{"In Init_Matlab_Sparse_Simple, index (" + to_string(index)
+                             + ") out of range for u vector max = "
+                             + to_string(Size+Size*Size)
+                             + " allocated = " + to_string(u_count_alloc)};
       if (NZE >= max_nze)
-        throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, exceeds the capacity of A_m sparse matrix\n");
+        throw FatalException{"In Init_Matlab_Sparse_Simple, exceeds the capacity of A_m sparse matrix"};
 #endif
       (*Ax)[NZE] = u[index];
       (*Ai)[NZE] = eq;
       NZE++;
 #ifdef DEBUG
       if (eq < 0 || eq >= Size)
-        throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, index (" + to_string(eq)
-                                     + ") out of range for b vector\n");
+        throw FatalException{"In Init_Matlab_Sparse_Simple, index (" + to_string(eq)
+                             + ") out of range for b vector"};
       if (var < 0 || var >= Size)
-        throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, index (" + to_string(var)
-                                     + ") out of range for index_vara vector\n");
+        throw FatalException{"In Init_Matlab_Sparse_Simple, index (" + to_string(var)
+                             + ") out of range for index_vara vector"};
       if (index_vara[var] < 0 || index_vara[var] >= y_size)
-        throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, index ("
-                                     + to_string(index_vara[var])
-                                     + ") out of range for y vector max=" + to_string(y_size)
-                                     + " (0)\n");
+        throw FatalException{"In Init_Matlab_Sparse_Simple, index ("
+                             + to_string(index_vara[var])
+                             + ") out of range for y vector max=" + to_string(y_size)
+                             + " (0)"};
 #endif
     }
   (*Ap)[Size] = NZE;
@@ -659,23 +659,23 @@ dynSparseMatrix::Init_UMFPACK_Sparse(int periods, int y_kmin, int y_kmax, int Si
   int n = periods * Size;
   *b = static_cast<double *>(mxMalloc(n * sizeof(double)));
   if (!(*b))
-    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, can't retrieve b vector\n");
+    throw FatalException{"In Init_UMFPACK_Sparse, can't retrieve b vector"};
   double *x0 = mxGetPr(x0_m);
   if (!x0)
-    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse_Simple, can't retrieve x0 vector\n");
+    throw FatalException{"In Init_UMFPACK_Sparse_Simple, can't retrieve x0 vector"};
   *Ap = static_cast<SuiteSparse_long *>(mxMalloc((n+1) * sizeof(SuiteSparse_long)));
   test_mxMalloc(*Ap, __LINE__, __FILE__, __func__, (n+1) * sizeof(SuiteSparse_long));
   if (!(*Ap))
-    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, can't allocate Ap index vector\n");
+    throw FatalException{"In Init_UMFPACK_Sparse, can't allocate Ap index vector"};
   size_t prior_nz = IM.size() * periods;
   *Ai = static_cast<SuiteSparse_long *>(mxMalloc(prior_nz * sizeof(SuiteSparse_long)));
   test_mxMalloc(*Ai, __LINE__, __FILE__, __func__, prior_nz * sizeof(SuiteSparse_long));
   if (!(*Ai))
-    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, can't allocate Ai index vector\n");
+    throw FatalException{"In Init_UMFPACK_Sparse, can't allocate Ai index vector"};
   *Ax = static_cast<double *>(mxMalloc(prior_nz * sizeof(double)));
   test_mxMalloc(*Ax, __LINE__, __FILE__, __func__, prior_nz * sizeof(double));
   if (!(*Ax))
-    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, can't retrieve Ax matrix\n");
+    throw FatalException{"In Init_UMFPACK_Sparse, can't retrieve Ax matrix"};
   for (int i = 0; i < y_size*(periods+y_kmin); i++)
     ya[i] = y[i];
 #ifdef DEBUG
@@ -760,20 +760,19 @@ dynSparseMatrix::Init_UMFPACK_Sparse(int periods, int y_kmin, int y_kmax, int Si
 
 #ifdef DEBUG
                               if (local_index < 0 || local_index >= Size * periods)
-                                throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index ("
-                                                             + to_string(local_index)
-                                                             + ") out of range for b vector\n");
+                                throw FatalException{"In Init_UMFPACK_Sparse, index ("
+                                                     + to_string(local_index)
+                                                     + ") out of range for b vector"};
                               if (k + row_x*flip_exo < 0 || k + row_x*flip_exo >= row_x * col_x)
-                                throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index ("
-                                                             + to_string(var+Size*(y_kmin+t+lag))
-                                                             + ") out of range for jacob_exo vector\n");
+                                throw FatalException{"In Init_UMFPACK_Sparse, index ("
+                                                     + to_string(var+Size*(y_kmin+t+lag))
+                                                     + ") out of range for jacob_exo vector"};
                               if (t+y_kmin+flip_exo*nb_row_x < 0
                                   || t+y_kmin+flip_exo*nb_row_x >= nb_row_x * this->col_x)
-                                throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index ("
-                                                             + to_string(index_vara[var+Size*(y_kmin+t+lag)])
-                                                             + ") out of range for x vector max="
-                                                             + to_string(nb_row_x * this->col_x)
-                                                             + "\n");
+                                throw FatalException{"In Init_UMFPACK_Sparse, index ("
+                                                     + to_string(index_vara[var+Size*(y_kmin+t+lag)])
+                                                     + ") out of range for x vector max="
+                                                     + to_string(nb_row_x * this->col_x)};
 #endif
                               u[k] -= jacob_exo[k + row_x*flip_exo] * x[t+y_kmin+flip_exo*nb_row_x];
                             }
@@ -792,7 +791,7 @@ dynSparseMatrix::Init_UMFPACK_Sparse(int periods, int y_kmin, int y_kmax, int Si
                 {
 #ifdef DEBUG
                   if (NZE >= max_nze)
-                    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, exceeds the capacity of A_m sparse matrix\n");
+                    throw FatalException{"In Init_UMFPACK_Sparse, exceeds the capacity of A_m sparse matrix"};
 #endif
                   if (!fliped)
                     {
@@ -804,21 +803,20 @@ dynSparseMatrix::Init_UMFPACK_Sparse(int periods, int y_kmin, int y_kmax, int Si
                     {
 #ifdef DEBUG
                       if (eq - lag * Size < 0 || eq  - lag * Size >= Size * periods)
-                        throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index ("
-                                                     + to_string(eq  - lag * Size)
-                                                     + ") out of range for b vector\n");
+                        throw FatalException{"In Init_UMFPACK_Sparse, index ("
+                                             + to_string(eq  - lag * Size)
+                                             + ") out of range for b vector"};
                       if (var+Size*(y_kmin+t) < 0
                           || var+Size*(y_kmin+t) >= Size*(periods+y_kmin+y_kmax))
-                        throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index ("
-                                                     + to_string(var+Size*(y_kmin+t))
-                                                     + ") out of range for index_vara vector\n");
+                        throw FatalException{"In Init_UMFPACK_Sparse, index ("
+                                             + to_string(var+Size*(y_kmin+t))
+                                             + ") out of range for index_vara vector"};
                       if (index_vara[var+Size*(y_kmin+t)] < 0
                           || index_vara[var+Size*(y_kmin+t)] >= y_size*(periods+y_kmin+y_kmax))
-                        throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index ("
-                                                     + to_string(index_vara[var+Size*(y_kmin+t)])
-                                                     + ") out of range for y vector max="
-                                                     + to_string(y_size*(periods+y_kmin+y_kmax))
-                                                     + "\n");
+                        throw FatalException{"In Init_UMFPACK_Sparse, index ("
+                                             + to_string(index_vara[var+Size*(y_kmin+t)])
+                                             + ") out of range for y vector max="
+                                             + to_string(y_size*(periods+y_kmin+y_kmax))};
 #endif
                       (*b)[eq - lag * Size] += u[index] * y[index_vara[var+Size*(y_kmin+t)]];
                     }
@@ -828,20 +826,20 @@ dynSparseMatrix::Init_UMFPACK_Sparse(int periods, int y_kmin, int y_kmax, int Si
                 {
 #ifdef DEBUG
                   if (eq < 0 || eq >= Size * periods)
-                    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index ("
-                                                 + to_string(eq)
-                                                 + ") out of range for b vector\n");
+                    throw FatalException{"In Init_UMFPACK_Sparse, index ("
+                                         + to_string(eq)
+                                         + ") out of range for b vector"};
                   if (var+Size*(y_kmin+t+lag) < 0
                       || var+Size*(y_kmin+t+lag) >= Size*(periods+y_kmin+y_kmax))
-                    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index ("
-                                                 + to_string(var+Size*(y_kmin+t+lag))
-                                                 + ") out of range for index_vara vector\n");
+                    throw FatalException{"In Init_UMFPACK_Sparse, index ("
+                                         + to_string(var+Size*(y_kmin+t+lag))
+                                         + ") out of range for index_vara vector"};
                   if (index_vara[var+Size*(y_kmin+t+lag)] < 0
                       || index_vara[var+Size*(y_kmin+t+lag)] >= y_size*(periods+y_kmin+y_kmax))
-                    throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index ("
-                                                 + to_string(index_vara[var+Size*(y_kmin+t+lag)])
-                                                 + ") out of range for y vector max="
-                                                 + to_string(y_size*(periods+y_kmin+y_kmax)) + "\n");
+                    throw FatalException{"In Init_UMFPACK_Sparse, index ("
+                                         + to_string(index_vara[var+Size*(y_kmin+t+lag)])
+                                         + ") out of range for y vector max="
+                                         + to_string(y_size*(periods+y_kmin+y_kmax))};
 #endif
                   (*b)[eq] += u[index+lag*u_count_init]*y[index_vara[var+Size*(y_kmin+t+lag)]];
                 }
@@ -850,11 +848,11 @@ dynSparseMatrix::Init_UMFPACK_Sparse(int periods, int y_kmin, int y_kmax, int Si
             {
 #ifdef DEBUG
               if (index < 0 || index >= u_count_alloc)
-                throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index (" + to_string(index)
-                                             + ") out of range for u vector\n");
+                throw FatalException{"In Init_UMFPACK_Sparse, index (" + to_string(index)
+                                     + ") out of range for u vector"};
               if (eq < 0 || eq >= (Size*periods))
-                throw FatalExceptionHandling(" in Init_UMFPACK_Sparse, index (" + to_string(eq)
-                                             + ") out of range for b vector\n");
+                throw FatalException{"In Init_UMFPACK_Sparse, index (" + to_string(eq)
+                                     + ") out of range for b vector"};
 #endif
               (*b)[eq] += u[index];
             }
@@ -912,19 +910,19 @@ dynSparseMatrix::Init_Matlab_Sparse(int periods, int y_kmin, int y_kmax, int Siz
   double *b = mxGetPr(b_m);
 
   if (!b)
-    throw FatalExceptionHandling(" in Init_Matlab_Sparse, can't retrieve b vector\n");
+    throw FatalException{"In Init_Matlab_Sparse, can't retrieve b vector"};
   double *x0 = mxGetPr(x0_m);
   if (!x0)
-    throw FatalExceptionHandling(" in Init_Matlab_Sparse_Simple, can't retrieve x0 vector\n");
+    throw FatalException{"In Init_Matlab_Sparse_Simple, can't retrieve x0 vector"};
   mwIndex *Aj = mxGetJc(A_m);
   if (!Aj)
-    throw FatalExceptionHandling(" in Init_Matlab_Sparse, can't allocate Aj index vector\n");
+    throw FatalException{"In Init_Matlab_Sparse, can't allocate Aj index vector"};
   mwIndex *Ai = mxGetIr(A_m);
   if (!Ai)
-    throw FatalExceptionHandling(" in Init_Matlab_Sparse, can't allocate Ai index vector\n");
+    throw FatalException{"In Init_Matlab_Sparse, can't allocate Ai index vector"};
   double *A = mxGetPr(A_m);
   if (!A)
-    throw FatalExceptionHandling(" in Init_Matlab_Sparse, can't retrieve A matrix\n");
+    throw FatalException{"In Init_Matlab_Sparse, can't retrieve A matrix"};
 
   for (int i = 0; i < y_size*(periods+y_kmin); i++)
     ya[i] = y[i];
@@ -963,12 +961,12 @@ dynSparseMatrix::Init_Matlab_Sparse(int periods, int y_kmin, int y_kmax, int Siz
                 {
 #ifdef DEBUG
                   if (index < 0 || index >= u_count_alloc || index > Size + Size*Size)
-                    throw FatalExceptionHandling(" in Init_Matlab_Sparse, index (" + to_string(index)
-                                                 + ") out of range for u vector max = "
-                                                 + to_string(Size+Size*Size) + " allocated = "
-                                                 + to_string(u_count_alloc) + "\n");
+                    throw FatalException{"In Init_Matlab_Sparse, index (" + to_string(index)
+                                         + ") out of range for u vector max = "
+                                         + to_string(Size+Size*Size) + " allocated = "
+                                         + to_string(u_count_alloc)};
                   if (NZE >= max_nze)
-                    throw FatalExceptionHandling(" in Init_Matlab_Sparse, exceeds the capacity of A_m sparse matrix\n");
+                    throw FatalException{"In Init_Matlab_Sparse, exceeds the capacity of A_m sparse matrix"};
 #endif
                   A[NZE] = u[index];
                   Ai[NZE] = eq - lag * Size;
@@ -978,19 +976,19 @@ dynSparseMatrix::Init_Matlab_Sparse(int periods, int y_kmin, int y_kmax, int Siz
                 {
 #ifdef DEBUG
                   if (eq < 0 || eq >= Size * periods)
-                    throw FatalExceptionHandling(" in Init_Matlab_Sparse, index (" + to_string(eq)
-                                                 + ") out of range for b vector\n");
+                    throw FatalException{"In Init_Matlab_Sparse, index (" + to_string(eq)
+                                         + ") out of range for b vector"};
                   if (var+Size*(y_kmin+t+lag) < 0
                       || var+Size*(y_kmin+t+lag) >= Size*(periods+y_kmin+y_kmax))
-                    throw FatalExceptionHandling(" in Init_Matlab_Sparse, index ("
-                                                 + to_string(var+Size*(y_kmin+t+lag))
-                                                 + ") out of range for index_vara vector\n");
+                    throw FatalException{"In Init_Matlab_Sparse, index ("
+                                         + to_string(var+Size*(y_kmin+t+lag))
+                                         + ") out of range for index_vara vector"};
                   if (index_vara[var+Size*(y_kmin+t+lag)] < 0
                       || index_vara[var+Size*(y_kmin+t+lag)] >= y_size*(periods+y_kmin+y_kmax))
-                    throw FatalExceptionHandling(" in Init_Matlab_Sparse, index ("
-                                                 + to_string(index_vara[var+Size*(y_kmin+t+lag)])
-                                                 + ") out of range for y vector max="
-                                                 + to_string(y_size*(periods+y_kmin+y_kmax)) + "\n");
+                    throw FatalException{"In Init_Matlab_Sparse, index ("
+                                         + to_string(index_vara[var+Size*(y_kmin+t+lag)])
+                                         + ") out of range for y vector max="
+                                         + to_string(y_size*(periods+y_kmin+y_kmax))};
 #endif
                   b[eq] += u[index+lag*u_count_init]*y[index_vara[var+Size*(y_kmin+t+lag)]];
                 }
@@ -999,11 +997,11 @@ dynSparseMatrix::Init_Matlab_Sparse(int periods, int y_kmin, int y_kmax, int Siz
             {
 #ifdef DEBUG
               if (index < 0 || index >= u_count_alloc)
-                throw FatalExceptionHandling(" in Init_Matlab_Sparse, index (" + to_string(index)
-                                             + ") out of range for u vector\n");
+                throw FatalException{"In Init_Matlab_Sparse, index (" + to_string(index)
+                                     + ") out of range for u vector"};
               if (eq < 0 || eq >= (Size*periods))
-                throw FatalExceptionHandling(" in Init_Matlab_Sparse, index (" + to_string(eq)
-                                             + ") out of range for b vector\n");
+                throw FatalException{"In Init_Matlab_Sparse, index (" + to_string(eq)
+                                     + ") out of range for b vector"};
 #endif
               b[eq] += u[index];
             }
@@ -1146,8 +1144,8 @@ dynSparseMatrix::Get_u()
           u_count_alloc += 5*u_count_alloc_save;
           u = static_cast<double *>(mxRealloc(u, u_count_alloc*sizeof(double)));
           if (!u)
-            throw FatalExceptionHandling(" in Get_u, memory exhausted (realloc("
-                                         + to_string(u_count_alloc*sizeof(double)) + "))\n");
+            throw FatalException{"In Get_u, memory exhausted (realloc("
+                                 + to_string(u_count_alloc*sizeof(double)) + "))"};
           int i = u_count;
           u_count++;
           return i;
@@ -1227,8 +1225,8 @@ dynSparseMatrix::compare(int *save_op, int *save_opa, int *save_opaa, int beg_t,
           i += 3;
           break;
         default:
-          throw FatalExceptionHandling(" in compare, unknown operator = "
-                                       + to_string(save_op_s->operat) + "\n");
+          throw FatalException{"In compare, unknown operator = "
+                               + to_string(save_op_s->operat)};
         }
       j++;
     }
@@ -1243,8 +1241,8 @@ dynSparseMatrix::compare(int *save_op, int *save_opa, int *save_opaa, int beg_t,
           u_count_alloc += max_save_ops_first;
           u = static_cast<double *>(mxRealloc(u, u_count_alloc*sizeof(double)));
           if (!u)
-            throw FatalExceptionHandling(" in compare, memory exhausted (realloc("
-                                         + to_string(u_count_alloc*sizeof(double)) + "))\n");
+            throw FatalException{"In compare, memory exhausted (realloc("
+                                 + to_string(u_count_alloc*sizeof(double)) + "))"};
         }
       for (int t = 1; t < periods-beg_t-y_kmax; t++)
         {
@@ -1982,16 +1980,16 @@ dynSparseMatrix::Solve_Matlab_Relaxation(mxArray *A_m, mxArray *b_m, unsigned in
 {
   double *b_m_d = mxGetPr(b_m);
   if (!b_m_d)
-    throw FatalExceptionHandling(" in Solve_Matlab_Relaxation, can't retrieve b_m vector\n");
+    throw FatalException{"In Solve_Matlab_Relaxation, can't retrieve b_m vector"};
   mwIndex *A_m_i = mxGetIr(A_m);
   if (!A_m_i)
-    throw FatalExceptionHandling(" in Solve_Matlab_Relaxation, can't retrieve Ir vector of matrix A\n");
+    throw FatalException{"In Solve_Matlab_Relaxation, can't retrieve Ir vector of matrix A"};
   mwIndex *A_m_j = mxGetJc(A_m);
   if (!A_m_j)
-    throw FatalExceptionHandling(" in Solve_Matlab_Relaxation, can't retrieve Jc vectior of matrix A\n");
+    throw FatalException{"In Solve_Matlab_Relaxation, can't retrieve Jc vectior of matrix A"};
   double *A_m_d = mxGetPr(A_m);
   if (!A_m_d)
-    throw FatalExceptionHandling(" in Solve_Matlab_Relaxation, can't retrieve double float data of matrix A\n");
+    throw FatalException{"In Solve_Matlab_Relaxation, can't retrieve double float data of matrix A"};
 
   /* Extract submatrices from the upper-left corner of A and subvectors at the
      beginning of b, so that the system looks like:
@@ -2321,7 +2319,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do
         {
           umfpack_dl_report_info(Control, Info);
           umfpack_dl_report_status(Control, status);
-          throw FatalExceptionHandling(" umfpack_dl_symbolic failed\n");
+          throw FatalException{"umfpack_dl_symbolic failed"};
         }
     }
   if (iter > 0)
@@ -2331,14 +2329,14 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do
     {
       umfpack_dl_report_info(Control, Info);
       umfpack_dl_report_status(Control, status);
-      throw FatalExceptionHandling(" umfpack_dl_numeric failed\n");
+      throw FatalException{"umfpack_dl_numeric failed"};
     }
   status = umfpack_dl_solve(sys, Ap, Ai, Ax, res, b, Numeric, Control, Info);
   if (status != UMFPACK_OK)
     {
       umfpack_dl_report_info(Control, Info);
       umfpack_dl_report_status(Control, status);
-      throw FatalExceptionHandling(" umfpack_dl_solve failed\n");
+      throw FatalException{"umfpack_dl_solve failed"};
     }
 
   if (vector_table_conditional_local.size())
@@ -2428,7 +2426,7 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do
         {
           umfpack_dl_report_info(Control, Info);
           umfpack_dl_report_status(Control, status);
-          throw FatalExceptionHandling(" umfpack_dl_symbolic failed\n");
+          throw FatalException{"umfpack_dl_symbolic failed"};
         }
     }
   if (iter > 0)
@@ -2438,14 +2436,14 @@ dynSparseMatrix::Solve_LU_UMFPack(SuiteSparse_long *Ap, SuiteSparse_long *Ai, do
     {
       umfpack_dl_report_info(Control, Info);
       umfpack_dl_report_status(Control, status);
-      throw FatalExceptionHandling(" umfpack_dl_numeric failed\n");
+      throw FatalException{"umfpack_dl_numeric failed"};
     }
   status = umfpack_dl_solve(sys, Ap, Ai, Ax, res, b, Numeric, Control, Info);
   if (status != UMFPACK_OK)
     {
       umfpack_dl_report_info(Control, Info);
       umfpack_dl_report_status(Control, status);
-      throw FatalExceptionHandling(" umfpack_dl_solve failed\n");
+      throw FatalException{"umfpack_dl_solve failed"};
     }
 
   if (is_two_boundaries)
@@ -2482,7 +2480,7 @@ dynSparseMatrix::Solve_Matlab_GMRES(mxArray *A_m, mxArray *b_m, int Size, double
   mxArray *lhs0[2];
   mxArray *rhs0[2] = { A_m, Setup };
   if (mexCallMATLAB(2, lhs0, 2, rhs0, "ilu"))
-    throw FatalExceptionHandling("In GMRES, the incomplete LU decomposition (ilu) has failed.");
+    throw FatalException("In GMRES, the incomplete LU decomposition (ilu) has failed");
   mxArray *L1 = lhs0[0];
   mxArray *U1 = lhs0[1];
   /*[za,flag1] = gmres(g1a,b,Blck_size,1e-6,Blck_size*periods,L1,U1);*/
@@ -2580,7 +2578,7 @@ dynSparseMatrix::Solve_Matlab_BiCGStab(mxArray *A_m, mxArray *b_m, int Size, dou
       mxArray *lhs0[2];
       mxArray *rhs0[2] = { A_m, Setup };
       if (mexCallMATLAB(2, lhs0, 2, rhs0, "ilu"))
-        throw FatalExceptionHandling(" In BiCGStab, the incomplete LU decomposition (ilu) has failed.\n");
+        throw FatalException{"In BiCGStab, the incomplete LU decomposition (ilu) has failed"};
       L1 = lhs0[0];
       U1 = lhs0[1];
       mxDestroyArray(Setup);
@@ -2763,10 +2761,10 @@ dynSparseMatrix::Singular_display(int block, int Size)
   mxDestroyArray(lhs[1]);
   mxDestroyArray(lhs[2]);
   if (block > 1)
-    throw FatalExceptionHandling(" in Solve_ByteCode_Sparse_GaussianElimination, singular system in block "
-                                 + to_string(block+1) + "\n");
+    throw FatalException{"In Solve_ByteCode_Sparse_GaussianElimination, singular system in block "
+                         + to_string(block+1)};
   else
-    throw FatalExceptionHandling(" in Solve_ByteCode_Sparse_GaussianElimination, singular system\n");
+    throw FatalException{"In Solve_ByteCode_Sparse_GaussianElimination, singular system"};
 }
 
 bool
@@ -2842,16 +2840,16 @@ dynSparseMatrix::Solve_ByteCode_Sparse_GaussianElimination(int Size, int blck, i
               if (blck > 1)
                 mexPrintf("Error: singular system in Simulate_NG in block %d\n", blck+1);
               else
-                mexPrintf("Error: singular system in Simulate_NG\n");
+                mexPrintf("Error: singular system in Simulate_NG");
               return true;
             }
           else
             {
               if (blck > 1)
-                throw FatalExceptionHandling(" in Solve_ByteCode_Sparse_GaussianElimination, singular system in block "
-                                             + to_string(blck+1) + "\n");
+                throw FatalException{"In Solve_ByteCode_Sparse_GaussianElimination, singular system in block "
+                                     + to_string(blck+1)};
               else
-                throw FatalExceptionHandling(" in Solve_ByteCode_Sparse_GaussianElimination, singular system\n");
+                throw FatalException{"In Solve_ByteCode_Sparse_GaussianElimination, singular system"};
             }
         }
       double markovitz = 0, markovitz_max = -9e70;
@@ -3049,7 +3047,7 @@ dynSparseMatrix::Solve_ByteCode_Symbolic_Sparse_GaussianElimination(int Size, bo
     {
 #ifdef MATLAB_MEX_FILE
       if (utIsInterruptPending())
-        throw UserExceptionHandling();
+        throw UserException{};
 #endif
 
       if (record && symbolic)
@@ -3201,10 +3199,10 @@ dynSparseMatrix::Solve_ByteCode_Symbolic_Sparse_GaussianElimination(int Size, bo
               if (piv_abs < eps)
                 {
                   if (Block_number > 1)
-                    throw FatalExceptionHandling(" in Solve_ByteCode_Symbolic_Sparse_GaussianElimination, singular system in block "
-                                                 + to_string(Block_number+1) + "\n");
+                    throw FatalException{"In Solve_ByteCode_Symbolic_Sparse_GaussianElimination, singular system in block "
+                                         + to_string(Block_number+1)};
                   else
-                    throw FatalExceptionHandling(" in Solve_ByteCode_Symbolic_Sparse_GaussianElimination, singular system\n");
+                    throw FatalException{"In Solve_ByteCode_Symbolic_Sparse_GaussianElimination, singular system"};
                 }
               /*divide all the non zeros elements of the line pivj by the max_pivot*/
               int nb_var = At_Row(pivj, &first);
@@ -3382,10 +3380,10 @@ dynSparseMatrix::Solve_ByteCode_Symbolic_Sparse_GaussianElimination(int Size, bo
               if (piv_abs < eps)
                 {
                   if (Block_number > 1)
-                    throw FatalExceptionHandling(" in Solve_ByteCode_Symbolic_Sparse_GaussianElimination, singular system in block "
-                                                 + to_string(Block_number+1) + "\n");
+                    throw FatalException{"In Solve_ByteCode_Symbolic_Sparse_GaussianElimination, singular system in block "
+                                         + to_string(Block_number+1)};
                   else
-                    throw FatalExceptionHandling(" in Solve_ByteCode_Symbolic_Sparse_GaussianElimination, singular system\n");
+                    throw FatalException{"In Solve_ByteCode_Symbolic_Sparse_GaussianElimination, singular system"};
                 }
               // Divide all the non zeros elements of the line pivj by the max_pivot
               int nb_var = At_Row(pivj, &first);
@@ -3684,12 +3682,11 @@ dynSparseMatrix::Simulate_One_Boundary(int block_num, int y_size, int size)
       else
         {
           if (iter == 0)
-            throw FatalExceptionHandling(" in Simulate_One_Boundary, The initial values of endogenous variables are too far from the solution.\nChange them!\n");
+            throw FatalException{"In Simulate_One_Boundary, The initial values of endogenous variables are too far from the solution. Change them!"};
           else
-            throw FatalExceptionHandling(" in Simulate_One_Boundary, Dynare cannot improve the simulation in block "
-                                         + to_string(block_num+1) + " at time " + to_string(it_+1)
-                                         + " (variable " + to_string(index_vara[max_res_idx]+1)
-                                         + "%d)\n");
+            throw FatalException{"In Simulate_One_Boundary, Dynare cannot improve the simulation in block "
+                                 + to_string(block_num+1) + " at time " + to_string(it_+1)
+                                 + " (variable " + to_string(index_vara[max_res_idx]+1)};
         }
     }
 
@@ -3729,13 +3726,13 @@ dynSparseMatrix::Simulate_One_Boundary(int block_num, int y_size, int size)
     {
       b_m = mxCreateDoubleMatrix(size, 1, mxREAL);
       if (!b_m)
-        throw FatalExceptionHandling(" in Simulate_One_Boundary, can't allocate b_m vector\n");
+        throw FatalException{"In Simulate_One_Boundary, can't allocate b_m vector"};
       A_m = mxCreateSparse(size, size, min(static_cast<int>(IM_i.size()*2), size * size), mxREAL);
       if (!A_m)
-        throw FatalExceptionHandling(" in Simulate_One_Boundary, can't allocate A_m matrix\n");
+        throw FatalException{"In Simulate_One_Boundary, can't allocate A_m matrix"};
       x0_m = mxCreateDoubleMatrix(size, 1, mxREAL);
       if (!x0_m)
-        throw FatalExceptionHandling(" in Simulate_One_Boundary, can't allocate x0_m vector\n");
+        throw FatalException{"In Simulate_One_Boundary, can't allocate x0_m vector"};
       if (!((solve_algo == 6 && steady_state)
             || ((stack_solve_algo == 0 || stack_solve_algo == 1 || stack_solve_algo == 4
                  || stack_solve_algo == 6) && !steady_state)))
@@ -3817,13 +3814,13 @@ dynSparseMatrix::solve_non_linear(int block_num, int y_size, int size)
   if (!cvg)
     {
       if (steady_state)
-        throw FatalExceptionHandling(" in Solve Forward/Backward Complete, convergence not achieved in block "
-                                     + to_string(block_num+1) + ", after " + to_string(iter)
-                                     + " iterations\n");
+        throw FatalException{"In Solve Forward/Backward Complete, convergence not achieved in block "
+                             + to_string(block_num+1) + ", after " + to_string(iter)
+                             + " iterations"};
       else
-        throw FatalExceptionHandling(" in Solve Forward/Backward Complete, convergence not achieved in block "
-                                     + to_string(block_num+1) + ", at time " + to_string(it_)
-                                     + ", after " + to_string(iter) + " iterations\n");
+        throw FatalException{"In Solve Forward/Backward Complete, convergence not achieved in block "
+                             + to_string(block_num+1) + ", at time " + to_string(it_)
+                             + ", after " + to_string(iter) + " iterations"};
     }
 }
 
@@ -3960,12 +3957,12 @@ dynSparseMatrix::Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin
                 mexPrintf("   variable %s (%d) at time %d = %f direction = %f\n", symbol_table.getName(SymbolType::endogenous, j).c_str(), j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]);
             }
           if (iter == 0)
-            throw FatalExceptionHandling(" in Simulate_Newton_Two_Boundaries, the initial values of endogenous variables are too far from the solution.\nChange them!\n");
+            throw FatalException{"In Simulate_Newton_Two_Boundaries, the initial values of endogenous variables are too far from the solution. Change them!"};
           else
-            throw FatalExceptionHandling(" in Simulate_Newton_Two_Boundaries, dynare cannot improve the simulation in block "
-                                         + to_string(blck+1) + " at time " + to_string(it_+1)
-                                         + " (variable " + to_string(index_vara[max_res_idx]+1)
-                                         + " = " + to_string(max_res) + ")\n");
+            throw FatalException{"In Simulate_Newton_Two_Boundaries, dynare cannot improve the simulation in block "
+                                 + to_string(blck+1) + " at time " + to_string(it_+1)
+                                 + " (variable " + to_string(index_vara[max_res_idx]+1)
+                                 + " = " + to_string(max_res) + ")"};
         }
       if (!(isnan(res1) || isinf(res1)) && !(isnan(g0) || isinf(g0))
           && (stack_solve_algo == 4 || stack_solve_algo == 5))
@@ -4099,15 +4096,15 @@ dynSparseMatrix::Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin
         {
           b_m = mxCreateDoubleMatrix(periods*Size, 1, mxREAL);
           if (!b_m)
-            throw FatalExceptionHandling(" in Simulate_Newton_Two_Boundaries, can't allocate b_m vector\n");
+            throw FatalException{"In Simulate_Newton_Two_Boundaries, can't allocate b_m vector"};
           x0_m = mxCreateDoubleMatrix(periods*Size, 1, mxREAL);
           if (!x0_m)
-            throw FatalExceptionHandling(" in Simulate_Newton_Two_Boundaries, can't allocate x0_m vector\n");
+            throw FatalException{"In Simulate_Newton_Two_Boundaries, can't allocate x0_m vector"};
           if (stack_solve_algo != 0 && stack_solve_algo != 4)
             {
               A_m = mxCreateSparse(periods*Size, periods*Size, IM_i.size()* periods*2, mxREAL);
               if (!A_m)
-                throw FatalExceptionHandling(" in Simulate_Newton_Two_Boundaries, can't allocate A_m matrix\n");
+                throw FatalException{"In Simulate_Newton_Two_Boundaries, can't allocate A_m matrix"};
             }
           if (stack_solve_algo == 0 || stack_solve_algo == 4)
             Init_UMFPACK_Sparse(periods, y_kmin, y_kmax, Size, IM_i, &Ap, &Ai, &Ax, &b, x0_m, vector_table_conditional_local, blck);
diff --git a/mex/sources/bytecode/bytecode.cc b/mex/sources/bytecode/bytecode.cc
index 86909afdb678122e715123c4bc5924c2aaebdf18..5445962d4b6a7973e3f907895d34bf567ff9cf3c 100644
--- a/mex/sources/bytecode/bytecode.cc
+++ b/mex/sources/bytecode/bytecode.cc
@@ -166,7 +166,7 @@ Get_Arguments_and_global_variables(int nrhs,
                 *plan_struct_name = deblank(Get_Argument(prhs[i]).substr(pos, string::npos));
               }
             else
-              throw FatalExceptionHandling(" in main, unknown argument : " + Get_Argument(prhs[i]) + "\n");
+              throw FatalException{"In main, unknown argument : " + Get_Argument(prhs[i])};
           }
     }
   if (count_array_argument > 0 && count_array_argument < 5)
@@ -174,20 +174,20 @@ Get_Arguments_and_global_variables(int nrhs,
       if (count_array_argument == 3 && steady_state)
         periods = 1;
       else
-        throw FatalExceptionHandling(" in main, missing arguments. All the following arguments have to be indicated y, x, params, it_, ys\n");
+        throw FatalException{"In main, missing arguments. All the following arguments have to be indicated y, x, params, it_, ys"};
     }
   *M_ = mexGetVariable("global", "M_");
   if (!*M_)
-    throw FatalExceptionHandling(" in main, global variable not found: M_\n");
+    throw FatalException{"In main, global variable not found: M_"};
 
   /* Gets variables and parameters from global workspace of Matlab */
   *oo_ = mexGetVariable("global", "oo_");
   if (!*oo_)
-    throw FatalExceptionHandling(" in main, global variable not found: oo_\n");
+    throw FatalException{"In main, global variable not found: oo_"};
 
   *options_ = mexGetVariable("global", "options_");
   if (!*options_)
-    throw FatalExceptionHandling(" in main, global variable not found: options_\n");
+    throw FatalException{"In main, global variable not found: options_"};
 }
 
 /* The gateway routine */
@@ -242,9 +242,9 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
                                          print, print_error, &GlobalTemporaryTerms,
                                          &plan, &pfplan, &extended_path, &extended_path_struct);
     }
-  catch (GeneralExceptionHandling &feh)
+  catch (GeneralException &feh)
     {
-      mexErrMsgTxt(feh.GetErrorMsg().c_str());
+      mexErrMsgTxt(feh.message.c_str());
     }
 #ifdef DEBUG
   mexPrintf("**************************************\n");
@@ -420,7 +420,7 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
               if (variable_type == SymbolType::exogenous)
                 splan[i].var_num = exo_num;
               else
-                mexErrMsgTxt(("The variable '"s + name + "'  defined as var in plan is not an exogenous\n").c_str());
+                mexErrMsgTxt(("The variable '"s + name + "'  defined as var in plan is not an exogenous").c_str());
             }
           tmp = mxGetField(plan_struct, i, "var");
           if (tmp)
@@ -432,7 +432,7 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
               if (variable_type == SymbolType::endogenous)
                 splan[i].exo_num = exo_num;
               else
-                mexErrMsgTxt(("The variable '"s + name + "'  defined as exo in plan is not an endogenous variable\n").c_str());
+                mexErrMsgTxt(("The variable '"s + name + "'  defined as exo in plan is not an endogenous variable").c_str());
             }
           tmp = mxGetField(plan_struct, i, "per_value");
           if (tmp)
@@ -480,7 +480,7 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
               if (variable_type == SymbolType::exogenous)
                 splan[i].var_num = exo_num;
               else
-                mexErrMsgTxt(("The variable '"s + name + "' defined as var in pfplan is not an exogenous\n").c_str());
+                mexErrMsgTxt(("The variable '"s + name + "' defined as var in pfplan is not an exogenous").c_str());
             }
           tmp = mxGetField(pfplan_struct, i, "exo");
           if (tmp)
@@ -492,7 +492,7 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
               if (variable_type == SymbolType::endogenous)
                 spfplan[i].exo_num = exo_num;
               else
-                mexErrMsgTxt(("The variable '"s + name + "' defined as exo in pfplan  is not an endogenous variable\n").c_str());
+                mexErrMsgTxt(("The variable '"s + name + "' defined as exo in pfplan  is not an endogenous variable").c_str());
             }
           tmp = mxGetField(pfplan_struct, i, "per_value");
           if (tmp)
@@ -685,10 +685,10 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
   string file_name = fname;
 
   if (stack_solve_algo == 7 && !steady_state)
-    mexErrMsgTxt("Bytecode: Can't use option stack_solve_algo=7\n");
+    mexErrMsgTxt("Bytecode: Can't use option stack_solve_algo=7");
 
   if (steady_state && !evaluate && (solve_algo < 5 || solve_algo > 8))
-    mexErrMsgTxt("Bytecode: solve_algo must be between 5 and 8 when using the internal steady state solver\n");
+    mexErrMsgTxt("Bytecode: solve_algo must be between 5 and 8 when using the internal steady state solver");
 
   size_t size_of_direction = col_y*row_y*sizeof(double);
   auto *y = static_cast<double *>(mxMalloc(size_of_direction));
@@ -727,11 +727,11 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
         {
           interprete.extended_path(f, f, evaluate, block, nb_blocks, max_periods, sextended_path, sconditional_extended_path, dates, table_conditional_global);
         }
-      catch (GeneralExceptionHandling &feh)
+      catch (GeneralException &feh)
         {
           // Release the lock on dynamic.bin for MATLAB+Windows, see #1815
           interprete.Close_SaveCode();
-          mexErrMsgTxt(feh.GetErrorMsg().c_str());
+          mexErrMsgTxt(feh.message.c_str());
         }
     }
   else
@@ -740,11 +740,11 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
         {
           interprete.compute_blocks(f, f, evaluate, block, nb_blocks);
         }
-      catch (GeneralExceptionHandling &feh)
+      catch (GeneralException &feh)
         {
           // Release the lock on dynamic.bin for MATLAB+Windows, see #1815
           interprete.Close_SaveCode();
-          mexErrMsgTxt(feh.GetErrorMsg().c_str());
+          mexErrMsgTxt(feh.message.c_str());
         }
     }
 
@@ -816,16 +816,16 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
                   plhs[1] = block_structur;
                   jacob_field_number = mxAddField(plhs[1], "g1");
                   if (jacob_field_number == -1)
-                    mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob to the structArray\n");
+                    mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob to the structArray");
                   jacob_exo_field_number = mxAddField(plhs[1], "g1_x");
                   if (jacob_exo_field_number == -1)
-                    mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob_exo to the structArray\n");
+                    mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob_exo to the structArray");
                   jacob_exo_det_field_number = mxAddField(plhs[1], "g1_xd");
                   if (jacob_exo_det_field_number == -1)
-                    mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob_exo_det to the structArray\n");
+                    mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob_exo_det to the structArray");
                   jacob_other_endo_field_number = mxAddField(plhs[1], "g1_o");
                   if (jacob_other_endo_field_number == -1)
-                    mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob_other_endo to the structArray\n");
+                    mexErrMsgTxt("Fatal error in bytecode: in main, cannot add extra field jacob_other_endo to the structArray");
                 }
               if (!dont_store_a_structure)
                 for (int i = 0; i < nb_blocks; i++)