refactor toplevel exception handling, see #6018

as a first step, i moved all the traceback formatting
to format_tb.

also, it **first** prints the error and then the traceback
as additional information for a bug report, as suggested
by @jimparis in that ticket.
This commit is contained in:
Thomas Waldmann 2023-04-08 00:12:06 +02:00
parent 48f3161248
commit b0b3d9e08c
No known key found for this signature in database
GPG Key ID: 243ACFA951F78E01
1 changed files with 38 additions and 18 deletions

View File

@ -561,6 +561,29 @@ def sig_trace_handler(sig_no, stack): # pragma: no cover
faulthandler.dump_traceback()
def format_tb(exc):
qualname = type(exc).__qualname__
remote = isinstance(exc, RemoteRepository.RPCError)
if remote:
prefix = "Borg server: "
trace_back = "\n".join(prefix + l for l in exc.exception_full.splitlines())
sys_info = "\n".join(prefix + l for l in exc.sysinfo.splitlines())
else:
trace_back = traceback.format_exc()
sys_info = sysinfo()
result = f"""
Error:
{qualname}: {exc}
If reporting bugs, please include the following:
{trace_back}
{sys_info}
"""
return result
def main(): # pragma: no cover
# Make sure stdout and stderr have errors='replace' to avoid unicode
# issues when print()-ing unicode file names
@ -591,12 +614,11 @@ def main(): # pragma: no cover
try:
args = archiver.get_args(sys.argv, os.environ.get("SSH_ORIGINAL_COMMAND"))
except Error as e:
msg = e.get_message()
tb_log_level = logging.ERROR if e.traceback else logging.DEBUG
tb = f"{traceback.format_exc()}\n{sysinfo()}"
# we might not have logging setup yet, so get out quickly
msg = e.get_message()
print(msg, file=sys.stderr)
if tb_log_level == logging.ERROR:
if e.traceback:
tb = format_tb(e)
print(tb, file=sys.stderr)
sys.exit(e.exit_code)
try:
@ -606,39 +628,37 @@ def main(): # pragma: no cover
msg = e.get_message()
msgid = type(e).__qualname__
tb_log_level = logging.ERROR if e.traceback else logging.DEBUG
tb = f"{traceback.format_exc()}\n{sysinfo()}"
tb = format_tb(e)
exit_code = e.exit_code
except RemoteRepository.RPCError as e:
important = e.exception_class not in ("LockTimeout",) and e.traceback
msg = e.exception_full if important else e.get_message()
msgid = e.exception_class
tb_log_level = logging.ERROR if important else logging.DEBUG
if important:
msg = e.exception_full
else:
msg = e.get_message()
tb = "\n".join("Borg server: " + l for l in e.sysinfo.splitlines())
tb += "\n" + sysinfo()
tb = format_tb(e)
exit_code = EXIT_ERROR
except Exception:
except Exception as e:
msg = "Local Exception"
msgid = "Exception"
tb_log_level = logging.ERROR
tb = f"{traceback.format_exc()}\n{sysinfo()}"
tb = format_tb(e)
exit_code = EXIT_ERROR
except KeyboardInterrupt:
except KeyboardInterrupt as e:
msg = "Keyboard interrupt"
tb_log_level = logging.DEBUG
tb = f"{traceback.format_exc()}\n{sysinfo()}"
tb = format_tb(e)
exit_code = EXIT_SIGNAL_BASE + 2
except SigTerm:
except SigTerm as e:
msg = "Received SIGTERM"
msgid = "Signal.SIGTERM"
tb_log_level = logging.DEBUG
tb = f"{traceback.format_exc()}\n{sysinfo()}"
tb = format_tb(e)
exit_code = EXIT_SIGNAL_BASE + 15
except SigHup:
except SigHup as e:
msg = "Received SIGHUP."
msgid = "Signal.SIGHUP"
tb_log_level = logging.DEBUG
tb = format_tb(e)
exit_code = EXIT_SIGNAL_BASE + 1
if msg:
logger.error(msg, msgid=msgid)