summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-04-20 20:30:27 +0900
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-04-23 17:19:58 +0900
commit3199d3573ef759b8b5496075856336d609e2a7ff (patch)
tree9ecf0cc605d3e6c5599748024429d06c5f323142
parentf7713400145f85c1c8386e552e5fc9c559a7bce3 (diff)
downloadbuildstream-tristan/except-hook-no-test.tar.gz
Overwrite sys.excepthook to handle exceptions in the main application.tristan/except-hook-no-test
This uses the existing messaging system to report errors in the main application as a BUG type. It requires the use of a global_app variable which isn't ideal; this may be replaced in future. This partially addresses issue #197. Theoretically, an exception could occur before Scheduler.loop is set up, hence the check for it when terminating all jobs. NOTE: This was originally submitted by Jim MacArthur, and manually reapplied after some refactoring took place.
-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
#