4

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
Gab
  • 63
  • 6
  • Suppressing the original traceback might make the program harder to debug for other users since the exception handling becomes non-obvious. – Brayoni Apr 27 '20 at 05:46

2 Answers2

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
user2357112
  • 260,549
  • 28
  • 431
  • 505
  • I'm using it just for special situations. `raise Exception('...') from None` does the trick, thanks! – Gab Apr 27 '20 at 10:59
0

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
Kuldeep Singh Sidhu
  • 3,748
  • 2
  • 12
  • 22