2009-08-18 7 views
7

Desde this question, ahora estoy haciendo un error de manejo de un nivel hacia abajo. Es decir, llamo a una función que llama a otra función más grande, y quiero donde falló en esa función más grande, no en la función más pequeña. Ejemplo específico El código es:Cuando encuentro una excepción, ¿cómo obtengo el tipo, archivo y número de línea del cuadro anterior?

import sys, os 

def workerFunc(): 
    return 4/0 

def runTest(): 
    try: 
     print workerFunc() 
    except: 
     ty,val,tb = sys.exc_info() 
     print "Error: %s,%s,%s" % (
      ty.__name__, 
      os.path.split(tb.tb_frame.f_code.co_filename)[1], 
      tb.tb_lineno) 

runTest() 

de salida es:

Error: ZeroDivisionError,tmp2.py,8 

pero la línea 8 es "imprimir workerFunc()" - Sé que la línea no, pero quiero la línea antes:

Error: ZeroDivisionError,tmp2.py,4 

Respuesta

4

Añadir una línea:

tb = tb.tb_next 

justo después de su llamada al sys.exc_info.

Consulte los documentos here en "Objetos de seguimiento".

2

Necesita encontrar la parte inferior de la trazabilidad, por lo que debe seguir hasta que no haya más cuadros. Haga esto para encontrar el cuadro que desea:

while tb.tb_next: 
    tb = tb.tb_next 

después de sys.exc_info. Esto encontrará la excepción sin importar cuántos marcos de llamadas haya caído.

3

tb.tb_next es su amigo:

import sys, os 

def workerFunc(): 
    return 4/0 

def runTest(): 
    try: 
     print workerFunc() 
    except: 
     ty,val,tb = sys.exc_info() 
     print "Error: %s,%s,%s" % (
      ty.__name__, 
      os.path.split(tb.tb_frame.f_code.co_filename)[1], 
      tb.tb_next.tb_lineno) 

runTest() 

Pero el traceback module hace esto y mucho más:

import traceback 

def workerFunc(): 
    return 4/0 

def runTest(): 
    try: 
     print workerFunc() 
    except: 
     print traceback.format_exc() 

runTest() 
Cuestiones relacionadas