2014-12-03 4 views
5

Ho un modulo di accesso al database che chiamo con una query o un comando. Capisce cosa fare con il database e cerca di farlo. Ad esempio, se la query o la stringa di comando è patologica, la chiamata al modulo PGDB sottostante può generare un'eccezione.Eccezioni di cattura che non ereditano dall'eccezione

Alcune informazioni incredibilmente utili vengono restituite da PGDB (da PostgreSQL sotto quello), specificando in particolare quali errori sono stati rilevati nella query o nel comando. Questo tipo di utilizzo delle varie funzioni di PGDB recupera le informazioni:

try: 
    pgdb.dothing(mod.withx) 
except Exception, e: 
    mod.error = 'pgdb.dothing('+str(type(mod.withx))+str(mod.withx)+') failed with: '+str(e) 

Poi, quando i rendimenti di classe, dopo aver fallito, l'oggetto contiene il messaggio in .error e viola, posso riparare la mia stupidità nella query o un comando.

E questo tutto sembra funzionare bene - (in Python 2.2.2, che potrebbe cambiare per 2.Higher un giorno ... ma non ora - e mai e poi mai a 3.whatever)

Ma ... ho trovato questo bit di opacità: "l'eccezione non deve essere ereditata da Exception, quindi plain 'except:' cattura tutte le eccezioni, non solo il sistema.Le eccezioni String sono un esempio di un'eccezione che non fa t ereditare da Exception "

Quindi, ecco la domanda: perché mi interessa? Se viene lanciata un'eccezione, voglio sapere perché. Non mi interessa da dove provenga, in realtà, voglio solo il messaggio di errore, e sicuramente non voglio che Python si fermi. Ciò includerebbe se l'errore provenisse dalla stringa o da qualsiasi altra cosa. Quindi, ad eccezione di prendere tutto è buono. O dovrebbe essere.

È che il parametro di Eccezione significa che non intendo un errore se proviene, ad esempio, dalle viscere della stringa? E quindi, il codice si fermerà con un'eccezione non rilevata? E quindi avrei bisogno di una serie di catture per ogni tipo che "non eredita dall'eccezione" per ottenere il comportamento che voglio? Qualcosa del genere:

try: 
    pgdb.dothing(mod.withx) 
except Exception, e: 
    mod.error = 'pgdb.dothing('+str(type(mod.withx))+str(mod.withx)+') failed with: '+str(e) 
except: 
    mod.error = 'pgdb.dothing('+str(type(mod.withx))+str(mod.withx)+') failed with: WTF???' 

... perché quello ... davvero fa schifo.

E, se questo è il caso, c'è un altro modo in cui posso catturare tutte le eccezioni di tutti i tipi e prendere il messaggio di errore per loro? Sembra che questo sia qualcosa che è altamente, altamente desiderabile (e sembra anche che un one-liner dovrebbe risolverlo, e dovrebbe sembrare un po 'come l'esempio precedente, piuttosto che il secondo.)

Per favore, prima tu rispondi: sì, so che Python 2.2.2 è vecchio. No, non verrà aggiornato presto. Questo è un sistema di produzione con diverse milioni di righe di codice; è stabile e vogliamo che rimanga così, basato su "non rotto, non fissato".

Ho solo bisogno di una solida comprensione di questa parte del processo di eccezione picchiato dentro di me. Tutte le spiegazioni sembrano fare supposizioni su ciò che so che sono ... ottimistiche. :)

Grazie per qualsiasi intuizione.

risposta

2

Prova questo, anche se questa è una cattiva pratica. Dovresti essere il più esplicito possibile quando si verificano errori irreversibili.

try: 
    ... 
except: 
    e = sys.exc_info() 
    print e 

Propongo inoltre di dare un'occhiata a https://wiki.python.org/moin/HandlingExceptions

+0

"Suggerisco anche di dare un'occhiata a ..." Ho fatto.E' dove ho ottenuto la citazione circa, tranne non sempre essendo da Eccezione da. Sembra che la tua risposta, sopra, faccia quello che ti sto chiedendo. Grazie mille. Inoltre, non sto ignorando gli errori. Sto provando a scoprire quale sia stato l'errore, e da quando ho Non ci sono quando succede, in generale, ho bisogno di catturare questo e farlo capire a me stesso - e all'utente, almeno in qualche modo: – fyngyrz

+0

@fyngyrz, Non è un problema. alla documentazione con le mie risposte Se la mia risposta ti ha aiutato, w non consideri di colpire il segno di spunta sulla sinistra? :-) – MeetTitan

1

Dai un'occhiata allo sys.exc_info() per ottenere le informazioni sull'eccezione nella tua clausola normale execpt:.

+0

Grazie. Questo fa parte di esso, va bene, ma sys.exc_info() restituisce (,,) per un errore di formattazione della query, mentre Exception, e restituisce lo specifico errore. quindi è entrambi: tranne: Exception, e: seguita da except: e capture from sys.exc_info() – fyngyrz

+1

Hai certamente ragione nel dire che la risposta più lunga è molto meglio della mia. Ma ti sbagli su ciò che 'sys.exc_info()' restituisce. Un valore come '(,,)' non esiste in Python. Dovrebbe essere il valore corretto triplo (tipo di eccezione, istanza di eccezione, traceback). Se ottieni un output di '(,,)' questo è probabilmente dovuto ad un inusuale frontend che stai utilizzando. – Alfe

+0

Interessante. L'unico front end di cui sono a conoscenza è PGDB. Quando rilevo Exception, e: ottengo i valori previsti. Quando catturo eccetto: solo, quindi e = sys.exc_info(), ciò che ottengo stampe come "(,,)" Potrebbe essere un artefatto del primo pitone o qualcosa del genere. Preparerò alcuni casi di test, è abbastanza facile da fare. Prossimo commento a breve – fyngyrz

4

Wow. Ci vorrà un po 'di tempo per disfare alcune delle assunzioni sbagliate in questa domanda.

La cattura di tutto non è affatto desiderabile. Come può essere? Se viene sollevata un'eccezione, è perché qualcosa è andato storto.Non è possibile scrivere codice che si occupi di ogni errore che potrebbe mai accadere, semplicemente perché nessun codice è perfetto. Quindi vengono sollevate eccezioni quando si verificano errori imprevedibili e si scrive codice di gestione per quelli che sai essere in grado di gestire.

Ma ciò lascia ancora cose che non è possibile gestire: perché vorresti catturarle? Cosa faresti, dopo averli catturati? Non ha senso dire "li accedo e proseguo", perché ora il tuo sistema si trova in uno stato indefinito. Esiste quel dato? Non lo so È stato scritto sul db? Non posso dirlo Hai appena perso milioni di entrate? Cerca me, guv.

Per quanto riguarda la versione Python, se il fatto che si sta eseguendo un sistema di produzione su una piattaforma non supportata su cui un gran numero di vulnerabilità gravi non solo sono state scoperte ma effettivamente sfruttate non conta come "interrotto", allora non so cosa fa

+1

Il punto in cui vengono catturati è che i livelli superiori possono passare quell'errore all'utente, che sta fissando un browser web, e non sarà minimamente illuminato da un messaggio del browser web che il CGI è andato capezzoli nord, e avvisare IT. Posso * meno * dire "Operazione DB fallita", quindi la tua sessione è chiusa. Il reparto IT è stato informato. "La tua ipotesi che" catch "=" continuare a prescindere "è fasulla. Per quanto riguarda l'assunzione di vulnerabilità, questi sistemi non sono sulla WAN. Sarebbe stato grandioso se tu avessi risposto alla domanda invece di chiamando snark (MAX) – fyngyrz

+2

Questo in realtà non risponde alla domanda.E 'un commento, anche se elaborato. – Veedrac