summaryrefslogtreecommitdiff
path: root/buildstream/_frontend/app.py
diff options
context:
space:
mode:
Diffstat (limited to 'buildstream/_frontend/app.py')
-rw-r--r--buildstream/_frontend/app.py21
1 files changed, 21 insertions, 0 deletions
diff --git a/buildstream/_frontend/app.py b/buildstream/_frontend/app.py
index 1ad1f059e..c32f8c90b 100644
--- a/buildstream/_frontend/app.py
+++ b/buildstream/_frontend/app.py
@@ -22,6 +22,7 @@ import os
import sys
import shutil
import resource
+import traceback
import datetime
from textwrap import TextWrapper
from contextlib import contextmanager
@@ -189,6 +190,10 @@ class App():
# Propagate pipeline feedback to the user
self.context.set_message_handler(self._message_handler)
+ # Now that we have a logger and message handler,
+ # we can override the global exception hook.
+ sys.excepthook = self._global_exception_handler
+
try:
self.project = Project(directory, self.context, cli_options=self._main_options['option'])
except LoadError as e:
@@ -550,6 +555,22 @@ class App():
self.context.message(
Message(None, message_type, message, **args))
+ # Exception handler
+ #
+ def _global_exception_handler(self, etype, value, tb):
+
+ # Print the regular BUG message
+ formatted = "".join(traceback.format_exception(etype, value, tb))
+ self._message(MessageType.BUG, str(value),
+ detail=formatted)
+
+ # If the scheduler has started, try to terminate all jobs gracefully,
+ # otherwise exit immediately.
+ if self.scheduler.loop:
+ self.scheduler.terminate_jobs()
+ else:
+ sys.exit(-1)
+
#
# Render the status area, conditional on some internal state
#