captura de mensajes de excepción en python

import ftplib
import urllib2
import os
import logging
logger = logging.getLogger('ftpuploader')
hdlr = logging.FileHandler('ftplog.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.INFO)
FTPADDR = "some ftp address"

def upload_to_ftp(con, filepath):
    try:
        f = open(filepath,'rb')                # file to send
        con.storbinary('STOR '+ filepath, f)         # Send the file
        f.close()                                # Close file and FTP
        logger.info('File successfully uploaded to '+ FTPADDR)
    except, e:
        logger.error('Failed to upload to ftp: '+ str(e))

Esto no parece funcionar, me da error de sintaxis, ¿cuál es la forma correcta de hacer esto para registrar todo tipo de excepciones a un archivo

Comentarios sobre la pregunta (4)
Solución

Tienes que definir qué tipo de excepción quieres atrapar. Así que escriba except Exception, e: en lugar de except, e: para una excepción general (que se registrará de todos modos).

Otra posibilidad es escribir todo el código try/except de esta manera:

try:
    with open(filepath,'rb') as f:
        con.storbinary('STOR '+ filepath, f)
    logger.info('File successfully uploaded to '+ FTPADDR)
except Exception, e:
    logger.error('Failed to upload to ftp: '+ str(e))

en Python 3.x y las versiones modernas de Python 2.x utiliza except Exception as e en lugar de except Exception, e:

try:
    with open(filepath,'rb') as f:
        con.storbinary('STOR '+ filepath, f)
    logger.info('File successfully uploaded to '+ FTPADDR)
except Exception as e:
    logger.error('Failed to upload to ftp: '+ str(e))
Comentarios (6)

Esta sintaxis ya no es compatible con python 3. Utilice lo siguiente en su lugar.

try:
    do_something()
except BaseException as e:
    logger.error('Failed to do something: ' + str(e))
Comentarios (8)

Actualizando esto a algo más simple para el registrador (funciona tanto para la pitón 2 como para la 3). No necesitas el módulo de rastreo.

import logging

logger = logging.Logger('catch_all')

def catchEverythingInLog():
    try:
        ... do something ...
    except Exception as e:
        logger.error(e, exc_info=True)
        ... exception handling ...

Esta es ahora la manera antigua (aunque todavía funciona):

import sys, traceback

def catchEverything():
    try:
        ... some operation(s) ...
    except:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        ... exception handling ...

exc_value es el mensaje de error.

Comentarios (2)

Hay algunos casos en los que puedes usar el e.message o e.messages.. Pero no funciona en todos los casos. De todos modos, lo más seguro es usar el str(e)

try:
  ...
except Exception as e:
  print(e.message)
Comentarios (1)

Puedes usar logger.exception("msg") para la excepción de registro con rastreo:

try:
    #your code
except Exception as e:
    logger.exception('Failed: ' + str(e))
Comentarios (2)

Si quieres la clase de error, el mensaje de error y el rastro de la pila (o algunos de ellos), usa sys.exec_info().

Código de trabajo mínimo con algún formato:

import sys
import traceback

try:
    ans = 1/0
except BaseException as ex:
    # Get current system exception
    ex_type, ex_value, ex_traceback = sys.exc_info()

    # Extract unformatter stack traces as tuples
    trace_back = traceback.extract_tb(ex_traceback)

    # Format stacktrace
    stack_trace = list()

    for trace in trace_back:
        stack_trace.append("File : %s , Line : %d, Func.Name : %s, Message : %s" % (trace[0], trace[1], trace[2], trace[3]))

    print("Exception type : %s " % ex_type.__name__)
    print("Exception message : %s" %ex_value)
    print("Stack trace : %s" %stack_trace)

Lo que da el siguiente resultado:

Exception type : ZeroDivisionError
Exception message : division by zero
Stack trace : ['File : .\\test.py , Line : 5, Func.Name : , Message : ans = 1/0']

[sys.exec_info()][1]

Esto le da detalles sobre la excepción más reciente. Devuelve una tupla de "tipo, valor, rastreo".

"Traceback" es una instancia de un objeto de rastreo. Puedes dar formato a la traza con los métodos proporcionados. Puedes encontrar más en la [documentación de traceback][2] .

[1]: https://docs.python.org/3.6/library/sys.html#sys.exc_info [2]: https://docs.python.org/3.6/library/traceback.html

Comentarios (1)

Después de Python 3.6, puedes usar el literal de cuerda formateada. ¡Es genial! (https://docs.python.org/3/whatsnew/3.6.html#whatsnew36-pep498)

try
 ...
except Exception as e:
    logger.error(f"Failed to upload to ftp: {e}")
Comentarios (0)

Puedes intentar especificar el tipo de BaseException explícitamente. Sin embargo, esto sólo atrapará derivados de BaseException. Aunque esto incluye todas las excepciones proporcionadas por la implementación, también es posible levantar clases arbitrarias de estilo antiguo.

try:
  do_something()
except BaseException, e:
  logger.error('Failed to do something: ' + str(e))
Comentarios (0)

Utilice str(ex) para imprimir la ejecución

try:
   #your code
except ex:
   print(str(ex))
Comentarios (0)