1

I use a list of different python scripts for various functions. To help facilitate this, I've organized all of my reusable functions into custom libraries. However, I found that many of these functions will error out for strange reasons, some known and some unknown. I designed the below function to at least let me see the error message before throwing a giant traceback at me. I have the below command in one library:

FooBar = trace_check(lambda: Foo(bar))

This is the error catching function in a separate library:

def trace_check(func):
    try:
        return func()
    except:
        TracebackString = traceback.format_exc() ###This gets the traceback as a string.
        type, message, tracebacklocation = sys.exc_info() ###This gets the components, particularly the message.
        print "An error has occurred with the following error message:"
        print type    ###Example is IOError
        print message     ###The message associated with the error
        TracebackPrompt = ask("Do you want to see the entire traceback?") #Returns True/False value
        if TracebackPrompt:
            print TracebackString
        print 'Exiting Python Script' ###This shows me it gets to this point.
        sys.exit(0)  ###This is the problem
        print "Did it work?"    ###This statement does not print, so exit worked...

When trace_check runs and I get an error, the sys.exit only quits the function back out to main() instead of ending main. if I use os._exit() instead, the main() function ends correctly, but the program running the script also dies. One command is not strong enough and the other is overkill... what could I do instead to ensure the main() function ends?

Note: I tried putting the meat of my trace_check function into the first library, but the same thing happens with the library call ending but not the main().

tl;dr - Python: main() calls function in library that calls a second function in separate library. Second function has a sys.exit() command that only exits to main() instead of ending main(). os._exit() kills shell and is overkill (requires restarting shell TT^TT). Is there another way to end the main() from a function library?

Sean Snyder
  • 624
  • 6
  • 3

2 Answers2

1

To directly answer your question, if you want to handle sys.exit() calls from main, then you should catch the SystemExit exception that is raised by sys.exit(). The sample code below illustrates how to do that.

import sys


def func():
    sys.exit(1)


def main():
    try:
        func()
    except SystemExit:
        print 'Someone sys.exit()d'
    return 0


if __name__ == '__main__':
    sys.exit(main())

However! You should probably redesign your library. Instead of calling sys.exit() when something unexpected happens, you should raise an Exception. Having a library abruptly exit the interpreter is bad design.

jaime
  • 2,234
  • 1
  • 19
  • 22
0

You could try setting this off by throwing an exception:

class ExitFromMain(Exception):
    pass   

def trace_check(func):
    try:
        # try stuff
    except:
        # traceback stuff you had
        raise ExitFromMain()

def main():
    try:
        # Stuff
        trace_check()
        # More stuff that will not run if the exception is thrown
    except ExitFromMain:
        print "I hit my excception to flag a quit from this function"
        sys.exit(0)
Farmer Joe
  • 6,020
  • 1
  • 30
  • 40