runtime
237 / 500
question 237 Debugging & Logging · medium

Follow a chained traceback

When an error happens while another one is being handled, Python prints both tracebacks, joined by a sentence: The above exception was the direct cause of the following exception: when the code used raise … from err, or During handling of the above exception, another exception occurred: when a second error happened inside an except block. Write error_chain(text) that reads such a pasted report and returns every error in it, from the original one to the last, with how each is linked to the one before.

Functionerror_chain(text)
texta full traceback as text; a chain has two or more parts separated by one of the two sentences
Returnsa list of (error_line, link) tuples in the order printed; error_line is the last non-blank line of that part, stripped
linkNone for the first error, "cause" after the *direct cause* sentence, "context" after the *During handling* sentence
Examples
callerror_chain('Traceback (most recent call last):\n File "main.py", line 6, in load\n return sugar(row)\n File "main.py", line 3, in sugar\n return float(row["sugars_100g"])\n ~~~^^^^^^^^^^^^^^^\nKeyError: \'sugars_100g\'\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File "main.py", line 10, in <module>\n load({"code": "3017620422003"})\n File "main.py", line 8, in load\n raise ValueError(f"product {row[\'code\']} has no sugar value") from err\nValueError: product 3017620422003 has no sugar value\n')returns[("KeyError: 'sugars_100g'", None), ('ValueError: product 3017620422003 has no sugar value', 'cause')]
callerror_chain('Traceback (most recent call last):\n File "main.py", line 15, in save\n return rows[0]["code"]\n ~~~~^^^\nIndexError: list index out of range\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File "main.py", line 19, in <module>\n save([])\n File "main.py", line 17, in save\n return undefined_name\n ^^^^^^^^^^^^^^\nNameError: name \'undefined_name\' is not defined\n')returns[('IndexError: list index out of range', None), ("NameError: name 'undefined_name' is not defined", 'context')]
callerror_chain('Traceback (most recent call last):\n File "a.py", line 1, in <module>\n 1 / 0\nZeroDivisionError: division by zero\n')returns[('ZeroDivisionError: division by zero', None)]

Loading your progress…

Follow a chained traceback — Python practice · Runtime