5

In my application I have a lot of conditions under which it is non-sensical to run the app further.

Currently I do something like this:

try:
    some_fun()
except Exception as e:
    print(f'Some short description: {str(e)}')
    sys.exit(1)

There is a lot of boilerplate so I'd like to avoid it. I'm looking for something that would allow me to pass the string Some short description as a parameter and automate handling the exception of any kind.

3 Answers 3

5

You can register a custom exception hook:

import sys


def print_and_quit(type, value, traceback):
    print("error:", value, file=sys.stderr)
    sys.exit("something went wrong...")


def main():
    sys.excepthook = print_and_quit
    # your app entrypoint here...


if __name__ == "__main__":
    main()

Note that the default except hook is already quite similar in behavior (printing a traceback and then exiting non-zero), but this allows to customize to do what you want instead. For example, to send an alert or log the exception to somewhere more useful for monitoring, suppress the traceback dump, exit differently for different types of errors, etc.

Sign up to request clarification or add additional context in comments.

Comments

2

You could do this:

def handle(func, desc):
    try:
        func()
    except Exception as e:
        print(f'{desc}: {str(e)}')
        sys.exit(1)

and use it as:

handle(lambda: 2/0, "some desc")

If you want args:

def handle(func, args, desc):
    try:
        func(*args)
    except Exception as e:
        print(f'{desc}: {str(e)}')
        exit(1)

and to call this:

handle(lambda arg1: 2/0, ["abc"], "some desc")

which will call the lambda with "abc". Also, as @Talon said:

Instead of having the function take a list of arguments, you can star your args argument and make desc a keyword argument. – Talon

Which you could implement as:

def handle(func, desc, *args)

and call as:

handle(lambda arg1: 2/0, "some desc", "abc")

Though that, @wim's solution is better, as long as you don't need to handle specific exceptions.

4 Comments

How about passing parameters to the func which may vary?
So now every line in the app has to be wrapped in handle? This just moves the same problem elsewhere
@wim -- I don't think there is another way to do it-- this shortens the code.
Instead of having the function take a list of arguments, you can star your args argument and make desc a keyword argument.
2

You can try using :

import sys
import traceback

def my_exception(s, t):
    #print(s) # the traceback is still available but not displayed
    if t == "error in code X":
        print("Something wrong but not critical\n")
        return 0
    elif t == "error in code Y":
        print("Something critical, need to exit\n")
        return 1
    return 1

try:
    val = int(".")
except:
    pass
    if my_exception(str(traceback.format_exc()), "error in code X"):
        sys.exit(1)
print("I'm still here\n")

try:
    val = 0/0
except:
    pass
    if my_exception(str(traceback.format_exc()), "error in code Y"):
        sys.exit(1)
print("I'll never run") 

Demo

2 Comments

This is a good example, except id doesn't lessen the number of lines.
@Xilpex I've rewrite the answer to hide any traceback

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.