traceback_with_variables icon indicating copy to clipboard operation
traceback_with_variables copied to clipboard

Support for chained exception

Open Luffbee opened this issue 8 months ago • 1 comments

An exception may be chained with the raise exc from e grammar, which sets the exc.__cause__ as e. Currently, print_exc does not print information about the cause exception. It will be better an option like follow_chain is added to print_exc and related functions to allow the chained exceptions be printed.

Here is an example code for a chained exception. I print it with printing_exc to show how this library handles it now. And for comparison, I also manually use print_exc(e.__cause__) to show the information of the cause exception.

from traceback_with_variables import printing_exc, print_exc


def bang(a, b, c):
    return a + b / c + c


def saver(x, y, z):
    exc = None
    try:
        bang(x, y, x + y - z)
    except Exception as e:
        exc = e
    return exc


def raiser(exc):
    raise RuntimeError("fail") from exc


def run(x, y, z):
    exc = saver(x, y, z)
    if exc is not None:
        raiser(exc)


def main():
    with printing_exc(reraise=False):
        run(1, 2, 3)

    print("------------------")
    print("------------------")
    print("------------------")

    try:
        run(1, 2, 3)
    except Exception as e:
        print_exc(e)
        cause = e.__cause__
        if isinstance(cause, Exception):
            print_exc(cause)
        # print("------------------")
        # raise
main()

The output is like follows (line number is wrong as the test.py has some unrelated comments):

Traceback with variables (most recent call last):
  File "test.py", line 54, in main
    run(1, 2, 3)
  File "test.py", line 48, in run
    raiser(exc)
      x = 1
      y = 2
      z = 3
      exc = division by zero
  File "test.py", line 42, in raiser
    raise RuntimeError("fail") from exc
      exc = division by zero
builtins.RuntimeError: fail
------------------
------------------
------------------
Traceback with variables (most recent call last):
  File "test.py", line 61, in main
    run(1, 2, 3)
      e = fail
  File "test.py", line 48, in run
    raiser(exc)
      x = 1
      y = 2
      z = 3
      exc = division by zero
  File "test.py", line 42, in raiser
    raise RuntimeError("fail") from exc
      exc = division by zero
builtins.RuntimeError: fail
Traceback with variables (most recent call last):
  File "test.py", line 35, in saver
    bang(x, y, x + y - z)
      x = 1
      y = 2
      z = 3
      exc = division by zero
  File "test.py", line 29, in bang
    return a + b / c + c
      a = 1
      b = 2
      c = 0
builtins.ZeroDivisionError: division by zero

Luffbee avatar May 07 '25 08:05 Luffbee

Thanks, I'll look into that

andy-landy avatar May 08 '25 22:05 andy-landy