Michael Rothkopf
Michael Rothkopf

Reputation: 128

How to remove the "Traceback most recent call last" in Python when raising an exception?

I am creating a Python program that requires the use of the OS module, and I would like to custom-report error messages. I am using try and except to accomplish this:

try:
    os.mkdir(name)
except FileExistsError:
    raise FileExistsError(name + "\n" + "                        ^ The directory you specified already exists.")

But, I would like to remove the

Traceback (most recent call last):
  File "file.py", line 20, in <module>
    raise FileExistsError(name + "\n" + "                        ^ The directory you specified already exists.")

part so that the code that raises this exception is not printed every time that I raise the exception.

How would I go about doing this?

Upvotes: 2

Views: 10154

Answers (2)

Adam Jenča
Adam Jenča

Reputation: 585

If you want to ignore the full traceback, there is an easy way:

try:
    ...
except FileExistsError as e:
    raise MyAppFileExists('message').with_traceback(None) from None

If you want to remove only the last part, it's a bit harder:

try:
    ...
except FileExistsError:
    try:
        raise MyAppFileExists('message')
    except MyAppFileExists as e:
        tb=e.__traceback__
        next_tb=tb
        while next_tb.tb_next.tb_next is not None:
            next_tb=next_tb.tb_next
        next_tb.tb_next=None
        raise e.with_traceback(tb) from None 

That from None means that Python should not printDuring handling of the above exception, another exception occurred:. If you want this to happpen, just remove the from None Part

Upvotes: 1

Paul Prescod
Paul Prescod

Reputation: 443

How most command line programs do it is to catch the exception near the top of the program where you interact with the user and print it out in a form that is useful to them:

def makedir(name):
    try:
        os.mkdir(name)
    except FileExistsError:
        raise FileExistsError(
            name + "\n" + "^ The directory you specified already exists."
        )


def main():
    try:
        makedir("/tmp")
    except FileExistsError as e:
        print("OOOPS", e)
        return

If you catch too broad of an exception class at the top, you will harm your own ability to debug and your user's ability to give you precise error messages, so you should be precise. In fact you might want to invent your own exception classes like this:

class MyAppExceptions(Exception):
    pass


class MyAppFileExists(MyAppExceptions):
    pass


def makedir(name):
    try:
        os.mkdir(name)
    except FileExistsError:
        raise MyAppFileExists(
            name + "\n" + "^ The directory you specified already exists."
        )


def main():
    try:
        makedir("/tmp")
    except MyAppFileExists as e:
        print("OOOPS", e)
        return

Then if your program gets a FileExistsError for a reason that you did not anticipate, you will still get an exception traceback that you can use for debugging.

Upvotes: 1

Related Questions