diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp
index bf573ac54378d1cfd08d619eb80bfbe69950a6ed..fbf7b60a21d0ea6aed9e9609d2b4c733a56fbcbc 100644
--- a/src/language/PugsParser.cpp
+++ b/src/language/PugsParser.cpp
@@ -126,6 +126,12 @@ parser(const std::string& filename)
       finalize();
       std::exit(1);
     }
+    catch (const IExitError& e) {
+      std::cerr << ASTBacktrace::getInstance().errorMessageAt(e.what()) << '\n';
+
+      finalize();
+      std::exit(1);
+    }
   } else {
     parse_and_execute(input);
   }
diff --git a/src/language/ast/ASTBacktrace.cpp b/src/language/ast/ASTBacktrace.cpp
index 90f84bf13fe46299797f11f478fd33f09e0571e9..f34eb0273b1b8d47b25a77a29eefd956e8602160 100644
--- a/src/language/ast/ASTBacktrace.cpp
+++ b/src/language/ast/ASTBacktrace.cpp
@@ -9,15 +9,14 @@ ASTBacktrace::ASTBacktrace(const std::shared_ptr<TAO_PEGTL_NAMESPACE::file_input
 {}
 
 std::string
-ASTBacktrace::stackInfo() const
+ASTBacktrace::errorMessageAt(const std::string& message) const
 {
   auto& stack = ASTBacktrace::getInstance().m_stack;
   std::ostringstream error_msg;
 
   auto p = stack[stack.size() - 1]->begin();
   error_msg << rang::style::bold << p.source << ':' << p.line << ':' << p.column << ": " << rang::style::reset
-            << rang::fgB::red << "error: " << rang::fg::reset << rang::style::bold << "emitted while executing"
-            << rang::style::reset << '\n';
+            << message << rang::fg::reset << '\n';
 
   if (m_file_input.use_count() > 0) {
     error_msg << m_file_input->line_at(p) << '\n'
diff --git a/src/language/ast/ASTBacktrace.hpp b/src/language/ast/ASTBacktrace.hpp
index 4dfc3c2ba5f8a8f3feca01a2a9edd41bf57d3f63..add4bc8b09f2c09c157a6d980104791a9cd89b08 100644
--- a/src/language/ast/ASTBacktrace.hpp
+++ b/src/language/ast/ASTBacktrace.hpp
@@ -22,7 +22,7 @@ class ASTBacktrace
   ~ASTBacktrace() = default;
 
  public:
-  std::string stackInfo() const;
+  std::string errorMessageAt(const std::string& error_msg) const;
 
   void
   push(const ASTNode* node)
diff --git a/src/language/node_processor/BuiltinFunctionProcessor.hpp b/src/language/node_processor/BuiltinFunctionProcessor.hpp
index 708141d17726102e944200f7c496e522885dfd61..e427160a44cbbb78be3067e6526e44e2f65c8b53 100644
--- a/src/language/node_processor/BuiltinFunctionProcessor.hpp
+++ b/src/language/node_processor/BuiltinFunctionProcessor.hpp
@@ -7,8 +7,6 @@
 #include <language/utils/BuiltinFunctionEmbedder.hpp>
 #include <language/utils/ParseError.hpp>
 
-#include <utils/SignalManager.hpp>
-
 class BuiltinFunctionExpressionProcessor final : public INodeProcessor
 {
  private:
@@ -86,18 +84,7 @@ class BuiltinFunctionProcessor : public INodeProcessor
       }
     }
 
-    if (SignalManager::pauseOnError()) {
-      // LCOV_EXCL_START
-      return m_function_expression_processor->execute(context_exec_policy);
-      // LCOV_EXCL_STOP
-    } else {
-      try {
-        return m_function_expression_processor->execute(context_exec_policy);
-      }
-      catch (std::runtime_error& e) {
-        throw ParseError(e.what(), {m_argument_node.begin()});
-      }
-    }
+    return m_function_expression_processor->execute(context_exec_policy);
   }
 
   BuiltinFunctionProcessor(ASTNode& argument_node) : m_argument_node{argument_node} {}
diff --git a/src/utils/Exceptions.cpp b/src/utils/Exceptions.cpp
index 1bf598b7ceac54e0cff3d8b2662b35bdc0654e07..5ffc6f943edc2afa489d0e50a4568cef7effb9da 100644
--- a/src/utils/Exceptions.cpp
+++ b/src/utils/Exceptions.cpp
@@ -10,23 +10,26 @@ RawError::RawError(std::string_view error_msg) : IExitError(std::string{error_ms
 NormalError::NormalError(std::string_view error_msg)
   : IExitError([&] {
       std::ostringstream os;
-      os << rang::style::bold << "error:" << rang::style::reset << ' ' << error_msg;
+      os << rang::fgB::red << "error:" << rang::style::reset << ' ' << error_msg;
       return os.str();
     }())
 {}
 
-UnexpectedError::UnexpectedError(std::string_view error_msg)
+UnexpectedError::UnexpectedError(std::string_view error_msg, const std::experimental::source_location& source_location)
   : IBacktraceError([&] {
       std::ostringstream os;
       os << rang::fgB::red << "unexpected error:" << rang::style::reset << ' ' << error_msg;
       return os.str();
-    }())
+    }()),
+    m_source_location{source_location}
 {}
 
-NotImplementedError::NotImplementedError(std::string_view error_msg)
+NotImplementedError::NotImplementedError(std::string_view error_msg,
+                                         const std::experimental::source_location& source_location)
   : IBacktraceError([&] {
       std::ostringstream os;
       os << rang::fgB::yellow << "not implemented yet:" << rang::style::reset << ' ' << error_msg;
       return os.str();
-    }())
+    }()),
+    m_source_location{source_location}
 {}
diff --git a/src/utils/Exceptions.hpp b/src/utils/Exceptions.hpp
index eb229198bc7fcc16d3d4216e859b66c6cf496376..46bfd60bd4b3f5b3cf5ca19c527595fcf92d34db 100644
--- a/src/utils/Exceptions.hpp
+++ b/src/utils/Exceptions.hpp
@@ -3,6 +3,9 @@
 
 #include <stdexcept>
 #include <string>
+#include <string_view>
+
+#include <experimental/source_location>
 
 struct IExitError : public std::runtime_error
 {
@@ -32,6 +35,8 @@ struct NormalError : public IExitError
 
 struct IBacktraceError : public std::runtime_error
 {
+  virtual const std::experimental::source_location& sourceLocation() const = 0;
+
   IBacktraceError(const IBacktraceError&) = delete;
   IBacktraceError(IBacktraceError&&)      = delete;
 
@@ -39,20 +44,42 @@ struct IBacktraceError : public std::runtime_error
   virtual ~IBacktraceError() = default;
 };
 
-struct UnexpectedError : IBacktraceError
+class UnexpectedError final : public IBacktraceError
 {
+ private:
+  const std::experimental::source_location m_source_location;
+
+ public:
+  const std::experimental::source_location&
+  sourceLocation() const
+  {
+    return m_source_location;
+  }
+
   UnexpectedError(const UnexpectedError&) = delete;
   UnexpectedError(UnexpectedError&&)      = delete;
 
-  UnexpectedError(std::string_view error_msg);
+  UnexpectedError(std::string_view error_msg,
+                  const std::experimental::source_location& = std::experimental::source_location::current());
 };
 
-struct NotImplementedError : IBacktraceError
+class NotImplementedError final : public IBacktraceError
 {
+ private:
+  const std::experimental::source_location m_source_location;
+
+ public:
+  const std::experimental::source_location&
+  sourceLocation() const
+  {
+    return m_source_location;
+  }
+
   NotImplementedError(const NotImplementedError&) = delete;
   NotImplementedError(NotImplementedError&&)      = delete;
 
-  NotImplementedError(std::string_view error_msg);
+  NotImplementedError(std::string_view error_msg,
+                      const std::experimental::source_location& = std::experimental::source_location::current());
 };
 
 #endif   // EXCEPTIONS_HPP
diff --git a/src/utils/SignalManager.cpp b/src/utils/SignalManager.cpp
index 1fb5c9949264c9bd6b6b8800d5ea344cf1c73566..f2721177285d3ed5c8edb7ca484a685679c94e5d 100644
--- a/src/utils/SignalManager.cpp
+++ b/src/utils/SignalManager.cpp
@@ -1,6 +1,7 @@
 #include <utils/SignalManager.hpp>
 
 #include <language/ast/ASTBacktrace.hpp>
+#include <language/utils/ParseError.hpp>
 #include <utils/BacktraceManager.hpp>
 #include <utils/ConsoleManager.hpp>
 #include <utils/Messenger.hpp>
@@ -78,24 +79,36 @@ SignalManager::handler(int signal)
     // Each failing process must write
     std::cerr.setstate(std::ios::goodbit);
 
-    std::ostringstream error_msg;
+    std::cerr << BacktraceManager{} << '\n';
 
-    BacktraceManager bm;
-    error_msg << bm;
-
-    std::cerr << error_msg.str() << '\n';
+    std::cerr << "\n *** " << rang::style::reset << rang::fg::reset << rang::style::bold << "Signal " << rang::fgB::red
+              << signalName(signal) << rang::fg::reset << " caught" << rang::style::reset << " ***\n\n";
 
     std::exception_ptr eptr = std::current_exception();
     try {
       if (eptr) {
         std::rethrow_exception(eptr);
+      } else {
+        std::ostringstream error_msg;
+        error_msg << "received " << signalName(signal);
+        std::cerr << ASTBacktrace::getInstance().errorMessageAt(error_msg.str()) << '\n';
       }
     }
-    catch (const NotImplementedError& not_implemented_error) {
-      std::cerr << not_implemented_error.what() << '\n';
+    catch (const IBacktraceError& backtrace_error) {
+      auto source_location = backtrace_error.sourceLocation();
+      std::cerr << rang::fgB::cyan << source_location.file_name() << ':' << source_location.line() << ':'
+                << source_location.column() << ':' << rang::fg::reset << rang::fgB::yellow
+                << " threw the following exception" << rang::fg::reset << "\n\n";
+      std::cerr << ASTBacktrace::getInstance().errorMessageAt(backtrace_error.what()) << '\n';
+    }
+    catch (const ParseError& parse_error) {
+      auto p = parse_error.positions().front();
+      std::cerr << rang::style::bold << p.source << ':' << p.line << ':' << p.column << ':' << rang::style::reset
+                << rang::fgB::red << " error: " << rang::fg::reset << rang::style::bold << parse_error.what()
+                << rang::style::reset << '\n';
     }
-    catch (const UnexpectedError& unexpected_error) {
-      std::cerr << unexpected_error.what() << '\n';
+    catch (const IExitError& exit_error) {
+      std::cerr << ASTBacktrace::getInstance().errorMessageAt(exit_error.what()) << '\n';
     }
     catch (const AssertError& assert_error) {
       std::cerr << assert_error << '\n';
@@ -104,11 +117,6 @@ SignalManager::handler(int signal)
       std::cerr << "Unknown exception!\n";
     }
 
-    std::cerr << "\n *** " << rang::style::reset << rang::fg::reset << rang::style::bold << "Signal " << rang::fgB::red
-              << signalName(signal) << rang::fg::reset << " caught" << rang::style::reset << " ***\n";
-
-    std::cerr << '\n' << ASTBacktrace::getInstance().stackInfo() << '\n';
-
     SignalManager::pauseForDebug(signal);
 
     mutex.unlock();