diff --git a/leapp/messaging/__init__.py b/leapp/messaging/__init__.py index 9896179e2..c42b5d7f5 100644 --- a/leapp/messaging/__init__.py +++ b/leapp/messaging/__init__.py @@ -146,6 +146,11 @@ def report_error(self, message, severity, actor, details): time=datetime.datetime.now()) self._do_produce(model, actor, self._errors) + def report_stacktrace(self, message, trace, actorname): + model = ErrorModel(message=message, details=trace, actor=actorname, severity="fatal", + time=datetime.datetime.now()) + self._do_produce(model, actorname, self._errors) + def request_stop_after_phase(self): """ If called, it will cause the workflow to stop the execution after the current phase ends. @@ -222,7 +227,7 @@ def _do_produce(self, model, actor, target, stored=True): data = json.dumps(model.dump(), sort_keys=True) message = { 'type': type(model).__name__, - 'actor': type(actor).name, + 'actor': type(actor).name if not isinstance(actor, str) else actor, 'topic': model.topic.name, 'stamp': datetime.datetime.utcnow().isoformat() + 'Z', 'phase': os.environ.get('LEAPP_CURRENT_PHASE', 'NON-WORKFLOW-EXECUTION'), diff --git a/leapp/workflows/__init__.py b/leapp/workflows/__init__.py index b909bb142..7f01e0d3e 100644 --- a/leapp/workflows/__init__.py +++ b/leapp/workflows/__init__.py @@ -338,8 +338,13 @@ def run(self, context=None, until_phase=None, until_actor=None, skip_phases_unti config_model=config_model, skip_dialogs=skip_dialogs) try: instance.run() - except BaseException: + except BaseException as exc: self._unhandled_exception = True + messaging.report_stacktrace(message=exc.message, + trace=exc.exception_info, + actorname=actor.name) + current_logger.error('Actor {actor} has crashed: {trace}'.format(actor=actor.name, + trace=exc.exception_info)) raise self._stop_after_phase_requested = messaging.stop_after_phase or self._stop_after_phase_requested