Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawback to catch-all exception (at highest program level, followed by re-raising, just to log before exiting?)

I have a long-running program on a remote machine and want to be sure that (1) I have a record of any exception that causes it to terminate and (2) someone is notified if it terminates. Does anyone see drawbacks to the method I am using? (or have recommendations for a better one?)

I've read the Python docs and many exception-related posts here, and understand that blanket except clauses are usually a bad idea. Within subroutines and modules I always use except to handle specific expected exceptions, but it seems useful to have a "catch-all" except clause at the highest level of the program to ensure I can log the exception before the program exits.

What do you think?

import traceback
try:
    # main program code here
except BaseException:
    tb = traceback.format_exc()
    msg = "Exiting program due to exception:" + tb
    LogToFile(msg)         # custom logging function
    SendAlertEmail(msg)    # warn admin that program terminated
    raise                  # program exits with the existing exception

Note that I was using BaseException instead of Exception because if someone at the terminal presses Ctrl-C, I would like to log that as the reason for exiting the program (and alert an admin that the program was exited). But I suppose I could also use:

except Exception, KeyboardInterrupt:
like image 486
emdash Avatar asked Jul 06 '10 01:07

emdash


People also ask

Is it good practice to catch a specific exception?

It is only good practice to catch a specific exception if it can actually be handled by the catch block. Very often, programmers assume that the fault can be handled at all, close to the point of occurrence. This is often wrong.

What happens when an exception is thrown in catch mode?

This matches the type of exception that was thrown, so the runtime system ends its search for an appropriate exception handler. Now that the runtime has found an appropriate handler, the code in that catch block is executed. After the exception handler executes, the runtime system passes control to the finally block.

How to catch all exceptions that signal program errors?

If you want to catch all exceptions that signal program errors, use except Exception: (bare except is equivalent to except BaseException: ). A good rule of thumb is to limit use of bare 'except' clauses to two cases: If the exception handler will be printing out or logging the traceback; at least the user will be aware that an error has occurred.

Why do we throw an exception early in the data layer?

Also the data layer is only responsible for requesting data, not for handling errors that occure while doing this. This is what meant by "throw early". In your example the catching layer is the service layer. The service itself is a new layer, sitting over the data access layer. So you want to catch the exception there.


1 Answers

There is no specific drawback, but there is an excellent alternative -- sys.excepthook.

In your specific version, consider using a bare except:, and sys.exc_info() to get the exception information; that will ensure you do catch everything -- even in the weird case where some module raises something else than an instance of a subclass of BaseException. E.g.:

>>> class X: pass
... 
>>> raise X
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.X: <__main__.X instance at 0xc9ad0>

As you see, it is still possible to raise something a except BaseException: would not catch -- that's why bare-except except: still exists (specifically for very special uses such as yours!).

Whether you use the hook, or build your own, consider (perhaps depending on configuration flags or environment settings) not burdening the end-user with all the details (just as a neat touch of improved user experience!), just a meaningful summary (reassuring the user that all details of the problem have been recorded, etc, etc).

like image 144
Alex Martelli Avatar answered Oct 05 '22 22:10

Alex Martelli