diff options
author | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-04-20 20:30:27 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-04-23 17:19:58 +0900 |
commit | 3199d3573ef759b8b5496075856336d609e2a7ff (patch) | |
tree | 9ecf0cc605d3e6c5599748024429d06c5f323142 | |
parent | f7713400145f85c1c8386e552e5fc9c559a7bce3 (diff) | |
download | buildstream-3199d3573ef759b8b5496075856336d609e2a7ff.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.py | 21 |
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 # |