Log exception in python

When exceptions happen, you may find it useful to log the exception and its stack trace for further investigation. In this article, you will learn how to retrieve the current exception and its properties – its type and its stack trace.

exc_info and traceback module

The exc_info] is viable tool to find information about currently handled exception. In other words, when called inside the except block of try except construct, this function will provide details about the exception being caught. The following data will be returned as a tuple with 3 values:

  • The value at position 1 is the type of the exception being caught
  • The value at position 2 is the exception being caught
  • The value at position 3 is a traceback object which contains data about call stack (stack trace) at the point when the exception occurred.

Consider the following snippet and its output:

exc_info sample #1 - the currently handled exception
 import sys
 try:
     xx = '1' + 5
 except Exception,ee:
     ( exception_type, exception , traceback ) = sys.exc_info()
     print 'The exception being handle (from except block ) ==> id : {0} , type: {1}'.format( id(ee) , type(ee)       )
     print 'The exception being handle (from sys.exc_info ) ==> id : {0} , type: {1}'.format( id(ee) , exception_type )
exc_info sample #1 output
 The excecption being handle (from except block ) ==> id : 37028088 , type: <type 'exceptions.TypeError'>
 The excecption being handle (from sys.exc_info ) ==> id : 37028088 , type: <type 'exceptions.TypeError'>

As we can see, the sys.exc_info() return the currently handled exception and its type (ee in the snippet). In the snippet, the function may seem not very useful since we already know which exception is handled from the except block. The full potential of this function derives from its ability to return the current exception even if it is called inside a function which is being called inside the except block:

exc_info sample #2 - the currently handled exception
 import sys
 def formatException():
     ( exception_type, exception , traceback ) = sys.exc_info()
     return 'The excecption being handle (from sys.exc_info ) ==> id : {0} , type: {1}'.format( id(ee) , exception_type )
 try:
     xx = '1' + 5
 except Exception,ee:
     print 'The excecption being handle (from except block ) ==> id : {0} , type: {1}'.format( id(ee) , type(ee)       )
     print formatException()
exc_info sample #2 output
 The excecption being handle (from except block ) ==> id : 37224736 , type: <type 'exceptions.TypeError'>
 The excecption being handle (from sys.exc_info ) ==> id : 37224736 , type: <type 'exceptions.TypeError'>

we can also use the value at position 3 of the tuple returned from sys.exc_info(). This value is a traceback object which contains the call stack state when the exception occurred. The traceback module contains functions which allow us to extract, format and print stack traces.

We will use the extract_tb from traceback module which return a list of tuples. Each tuple in the list represent a function in the call stack. The tuple:

  • The value at position 3 is the function name
  • The value at position 1 is the file where this function is defined
  • The value at position 2 is the line in this file where the next function in the call stack was invoked. Please note, In the last function, this will be the number of the line where the excecption was raised.
  • The value at position 4 is contents of this line