in src/buildstream/_frontend/app.py [0:0]
def _handle_failure(self, element, task, failure):
full_name = task.full_name
# Handle non interactive mode setting of what to do when a job fails.
if not self._interactive_failures:
if self.context.sched_error_action == _SchedulerErrorAction.TERMINATE:
self.stream.terminate()
elif self.context.sched_error_action == _SchedulerErrorAction.QUIT:
self.stream.quit()
elif self.context.sched_error_action == _SchedulerErrorAction.CONTINUE:
pass
return
# Interactive mode for element failures
with self._interrupted():
summary = (
"\n{} failure on element: {}\n".format(failure.action_name, full_name)
+ "\n"
+ "Choose one of the following options:\n"
+ " (c)ontinue - Continue queueing jobs as much as possible\n"
+ " (q)uit - Exit after all ongoing jobs complete\n"
+ " (t)erminate - Terminate any ongoing jobs and exit\n"
+ " (r)etry - Retry this job\n"
)
if failure.logfile:
summary += " (l)og - View the full log file\n"
if failure.sandbox:
summary += " (s)hell - Drop into a shell in the failed build sandbox\n"
summary += "\nPressing ^C will terminate jobs and exit\n"
choices = ["continue", "quit", "terminate", "retry"]
if failure.logfile:
choices += ["log"]
if failure.sandbox:
choices += ["shell"]
choice = ""
while choice not in ["continue", "quit", "terminate", "retry"]:
click.echo(summary, err=True)
self._notify("BuildStream failure", "{} on element {}".format(failure.action_name, full_name))
try:
choice = click.prompt(
"Choice:", default="continue", err=True, value_proc=_prefix_choice_value_proc(choices)
)
except (click.Abort, SystemError):
# In some cases, the readline buffer underlying the prompt gets corrupted on the second CTRL+C
# This throws a SystemError, which doesn't seem to be problematic for the rest of the program
# Ensure a newline after automatically printed '^C'
click.echo("", err=True)
choice = "terminate"
# Handle choices which you can come back from
#
if choice == "shell":
click.echo("\nDropping into an interactive shell in the failed build sandbox\n", err=True)
try:
unique_id, _ = element
self.stream.shell(
None,
_Scope.BUILD,
self.shell_prompt,
isolate=True,
usebuildtree=True,
unique_id=unique_id,
)
except BstError as e:
click.echo("Error while attempting to create interactive shell: {}".format(e), err=True)
elif choice == "log":
with open(failure.logfile, "r", encoding="utf-8") as logfile:
content = logfile.read()
click.echo_via_pager(content)
if choice == "terminate":
click.echo("\nTerminating all jobs\n", err=True)
self.stream.terminate()
else:
if choice == "quit":
click.echo("\nCompleting ongoing tasks before quitting\n", err=True)
self.stream.quit()
elif choice == "continue":
click.echo("\nContinuing with other non failing elements\n", err=True)
elif choice == "retry":
click.echo("\nRetrying failed job\n", err=True)
unique_id = element[0]
self.stream.retry_job(task.action_name, unique_id)