Python only print traceback of raised exception
Asked Answered
Q

2

5

I'm raising a new exception in try-except block with additional message. The original exception traceback is therefore not needed anymore. Is there any way to remove the original traceback and only print the traceback of the newly raised exception?

Example Code (Python 3.6.10):

try:
    10/0
except:
    raise Exception('some error')

Output:

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
d:\xxx\main.py in 
      1 try:
----> 2     10/0
      3 except:

ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Exception                                 Traceback (most recent call last)
d:\xxx\main.py in 
      2     10/0
      3 except:
----> 4     raise Exception('some error')

Exception: some error

Desired output:

---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
d:\xxx\main.py in 
      2     10/0
      3 except:
----> 4     raise Exception('some error')

Exception: some error
Quadripartite answered 27/4, 2020 at 5:3 Comment(1)
Suppressing the original traceback might make the program harder to debug for other users since the exception handling becomes non-obvious.Rodin
R
5

I'm raising a new exception in try-except block with additional message. The original exception traceback is therefore not needed anymore.

You can discard the original exception, but I would reconsider that decision. The reason exception causes and contexts were added in Python 3 is because information about the original exception and stack trace is useful. I'd explicitly mark the original exception as the cause of the new exception, which changes the message a bit:

try:
    1/0
except ZeroDivisionError as e:
    raise Exception("Oh crud") from e

Output:

Traceback (most recent call last):
  File "main.py", line 2, in <module>
    1/0
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "main.py", line 4, in <module>
    raise Exception("Oh crud") from e
Exception: Oh crud

That said, if you really want to suppress information about the original exception, you can use None as the cause of the new exception:

try:
    1/0
except ZeroDivisionError:
    raise Exception("Oh crud") from None

Output:

Traceback (most recent call last):
  File "main.py", line 4, in <module>
    raise Exception("Oh crud") from None
Exception: Oh crud
Rockafellow answered 27/4, 2020 at 5:33 Comment(1)
I'm using it just for special situations. raise Exception('...') from None does the trick, thanks!Quadripartite
P
1

Use with_traceback

import sys, traceback
try:
    10/0
except Exception as exc:
    raise  exc.with_traceback(None)
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-31-d77f0aded0d7> in <module>()
      3     10/0
      4 except Exception as exc:
----> 5     raise  exc.with_traceback(None)

ZeroDivisionError: division by zero

If you just want to show it:

import sys, traceback
try:
    10/0
except Exception:
    ex_type, ex, tb = sys.exc_info()
    traceback.print_tb(tb)
File "<ipython-input-4-1283199eb169>", line 3, in <module>
    10/0

ALTERNATIVE

import sys, traceback
try:
    10/0
except Exception as exc:
    tb_str = traceback.format_exception(etype=type(exc), value=exc, tb=exc.__traceback__)
    for i in tb_str: print(i)
Traceback (most recent call last):

  File "<ipython-input-17-3bc95dc2ebf5>", line 3, in <module>
    10/0

ZeroDivisionError: division by zero
Psychologist answered 27/4, 2020 at 5:6 Comment(1)
By way of update, format_exception (no longer?) does not have an etype parameter. Now, the line should simply read: traceback.format_exception(exc).Remembrancer

© 2022 - 2024 — McMap. All rights reserved.