Some Name
Some Name

Reputation: 9521

How to handle exception and exit?

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.

Upvotes: 5

Views: 356

Answers (3)

Pedro Lobito
Pedro Lobito

Reputation: 98921

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

Upvotes: 2

wim
wim

Reputation: 362717

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.

Upvotes: 5

xilpex
xilpex

Reputation: 3237

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.

Upvotes: 2

Related Questions