acquisizione del messaggio di eccezione python


521
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))

Questo non sembra funzionare, ottengo un errore di sintassi, qual è il modo corretto di farlo per registrare tutti i tipi di eccezioni in un file


2
Il tuo rientro è rotto. E omettere il ,dopo except.
Sven Marnach,

3
@SvenMarnach, se ometti il ,dopo except, otterrai global name 'e' is not defined, il che non è molto meglio della sintassi sbagliata.
Val

12
@Val: dovrebbe essere except Exception as eo except Exception, e, a seconda della versione di Python.
Sven Marnach,

1
Probabilmente è da qualche parte intorno a quelle 8 risposte, ma quando apri un file, la parte chiusa non dovrebbe mai essere all'interno dell'istruzione try, ma in un'istruzione finally o racchiusa in un'istruzione with.
JC Rocamonde,

Risposte:


734

Devi definire quale tipo di eccezione vuoi catturare. Quindi scrivi except Exception, e:invece che except, e:per un'eccezione generale (che verrà comunque registrata).

Un'altra possibilità è scrivere l'intero codice try / tranne in questo modo:

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

in Python 3.xe nelle versioni moderne di Python 2.x except Exception as einvece di 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: # work on python 3.x
    logger.error('Failed to upload to ftp: '+ str(e))

118
repr (e) ti dà l'eccezione (e la stringa di messaggio); str (e) fornisce solo la stringa di messaggio.
Barbabianca

11
In alternativa, è possibile utilizzare l'eccezione di registrazione logger.exception(e). Registrerà l'eccezione con traceback allo stesso logging.ERRORlivello.
mbdevpl,

1
@mbdevpl questo non sembra essere vero. Sembra chiamare str () sull'eccezione
KevinOrr

6
except Exception, e:genera un errore di sintassi per me in Python 3. È previsto?
Charlie Parker,

27
@CharlieParker in Python3 scrivereexcept Exception as e:
eumiro

282

La sintassi non è più supportata in Python 3. Utilizzare invece quanto segue.

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

2
In realtà, dovresti usare logger.error ('Impossibile fare qualcosa:% s', str (e)) In questo modo, se il tuo livello di logger è al di sopra dell'errore non esegue l'interpolazione di stringhe.
avyfain,

7
@avyfain - Sei errato. L'istruzione logging.error('foo %s', str(e))verrà sempre convertita ein una stringa. Per ottenere ciò che desideri, useresti logging.error('foo %s', e), permettendo così al framework di logging di fare (o non fare) la conversione.
Ron Dahlgren,

1
Puoi verificare in un REPL di Python (qui con Python 3.5.2 e ipython): guarda qui il mio
Ron Dahlgren,

2
In alternativa, è possibile utilizzare l'eccezione di registrazione logger.exception(e). Registrerà l'eccezione con traceback allo stesso logging.ERRORlivello.
mbdevpl,

11
Fai attenzione except BaseExceptione except Exceptionnon sono allo stesso livello. except Exceptionfunziona in Python3, ma non prenderà KeyboardInterruptad esempio (il che può essere molto comodo se vuoi essere in grado di interrompere il tuo codice!), mentre BaseExceptionrileva qualsiasi eccezione. Vedi questo link per la gerarchia delle eccezioni.
jeannej,

41

Aggiornamento a qualcosa di più semplice per il logger (funziona sia per Python 2 che per 3). Non è necessario il modulo traceback.

import logging

logger = logging.Logger('catch_all')

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

Questo è ora alla vecchia maniera (anche se funziona ancora):

import sys, traceback

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

exc_value è il messaggio di errore.


2
Questo sarebbe il mio metodo preferito. La sola stampa della stringa è utile per la registrazione, suppongo, ma se devo fare qualcosa con queste informazioni, ho bisogno di più di una semplice stringa.
Sulimmesh,

3
Non è necessario "importare traceback" nel secondo esempio, giusto?
starikoff,

34

Ci sono alcuni casi in cui è possibile utilizzare l' e.message o e.messages .. Ma non funziona in tutti i casi. Ad ogni modo, più sicuro è usare str (e)

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

42
Il problema con questo è, per esempio, se si except Exception as e, ed eè una IOError, si ottiene e.errno, e.filenamee e.strerror, ma a quanto pare no e.message(almeno in Python 2.7.12). Se si desidera acquisire il messaggio di errore, utilizzare str(e), come nelle altre risposte.
epmo

@epalm Cosa succede se si rileva l'errore IO prima dell'eccezione?
Albert Thompson,

@ HeribertoJuárez Perché catturare casi speciali mentre puoi semplicemente lanciarlo su una stringa?
HosseyNJF

25

Se si desidera la classe di errore, il messaggio di errore e la traccia dello stack (o alcuni di questi), utilizzare sys.exec_info().

Codice di lavoro minimo con alcune formattazioni:

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)

Che dà il seguente risultato:

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

La funzione sys.exc_info () fornisce dettagli sull'eccezione più recente. Restituisce una tupla di (type, value, traceback).

tracebackè un'istanza di oggetto traceback. È possibile formattare la traccia con i metodi forniti. Ulteriori informazioni sono disponibili nella documentazione di traceback .


3
L'utilizzo e.__class__.__name__ può restituire anche la classe di eccezione.
Kenorb,

19

È possibile utilizzare logger.exception("msg")per la registrazione dell'eccezione con traceback:

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

Per coincidenza, e.msgè la rappresentazione in forma di stringa della Exceptionclasse.
MarkHu

5
O semplicemente logger.exception(e).
mbdevpl,


5

Puoi provare a specificare esplicitamente il tipo BaseException. Tuttavia, questo prenderà solo derivati ​​di BaseException. Sebbene ciò includa tutte le eccezioni fornite dall'implementazione, è anche possibile che vengano generate classi arbitrarie di vecchio stile.

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

4

Usa str (ex) per stampare l'esecuzione

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

2

per i futuri lottatori, in Python 3.8.2 (e forse alcune versioni precedenti), la sintassi è

except Attribute as e:
    print(e)

1

Usando str(e)o repr(e)per rappresentare l'eccezione, non otterrai la traccia dello stack effettiva, quindi non è utile trovare dove si trova l'eccezione.

Dopo aver letto le altre risposte e il documento del pacchetto di registrazione, i due modi seguenti funzionano perfettamente per stampare la traccia dello stack effettiva per un debug più semplice:

utilizzare logger.debug()con il parametroexc_info

try:
    # my code
exception SomeError as e:
    logger.debug(e, exc_info=True)

uso logger.exception()

oppure possiamo usare direttamente logger.exception()per stampare l'eccezione.

try:
    # my code
exception SomeError as e:
    logger.exception(e)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.