Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Locating the line number where an exception occurs in python code

I have a code similar to this:

try:
  if x:
      statement1
      statement2
      statement3
  elif y:
      statement4
      statement5
      statement6
  else:
      raise

except:
      statement7

Here, I am sure that the exception occurs in If x: block, but I would like to know in which statement of If x: block the exception occurs. Is there a way to get the line number where the exception occurs?

Regards,

like image 485
alwbtc Avatar asked Aug 05 '11 19:08

alwbtc


2 Answers

what about this:

try:
  if x:
      print 'before statement 1'
      statement1
      print 'before statement 2' #ecc. ecc.
      statement2
      statement3
  elif y:
      statement4
      statement5
      statement6
  else:
      raise

except:
      statement7

this is the straightforward workaround but I suggest to use a debugger

or even better, use the sys module :D

try:
      if x:
          print 'before statement 1'
          statement1
          print 'before statement 2' #ecc. ecc.
          statement2
          statement3
      elif y:
          statement4
          statement5
          statement6
      else:
          raise
except:
    print sys.exc_traceback.tb_lineno 
    #this is the line number, but there are also other infos
like image 160
Ant Avatar answered Sep 25 '22 21:09

Ant


I believe the several answers here recommending you manage your try/except blocks more tightly are the answer you're looking for. That's a style thing, not a library thing.

However, at times we find ourselves in a situation where it's not a style thing, and you really do need the line number to do some other programattic action. If that's what you're asking, you should consider the traceback module. You can extract all the information you need about the most recent exception. The tb_lineno function will return the line number causing the exception.

>>> import traceback
>>> dir(traceback)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_format_final_exc_line', '_print', '_some_str', 'extract_stack', 'extract_tb', 'format_exc', 'format_exception', 'format_exception_only', 'format_list', 'format_stack', 'format_tb', 'linecache', 'print_exc', 'print_exception', 'print_last', 'print_list', 'print_stack', 'print_tb', 'sys', 'tb_lineno', 'types']
>>> help(traceback.tb_lineno)
Help on function tb_lineno in module traceback:

tb_lineno(tb)
Calculate correct line number of traceback given in tb.
Obsolete in 2.3

Newer versions of the traceback plumbing fix the issue prior to 2.3, allowing the code below to work as it was intended: (this is the "right way")

import traceback
import sys

try:
    raise Exception("foo")
except:
    for frame in traceback.extract_tb(sys.exc_info()[2]):
        fname,lineno,fn,text = frame
        print "Error in %s on line %d" % (fname, lineno)
like image 30
J.J. Avatar answered Sep 21 '22 21:09

J.J.