Eccezioni e librerie

1

Sto scrivendo una libreria che sarà una base per un sistema di battaglia a turni ma non so quali sono le migliori pratiche per la gestione delle eccezioni, qualcuno ha qualche consiglio per me?

Devo rilevare tutte le eccezioni / eccezioni generiche generate da componenti standard (come elenchi, dizionari, ecc.) e poi lanciare un'eccezione contestualizzata?

Se ho un metodo pubblico che genera un'eccezione, quando lo chiamo da un altro metodo di libreria dovrei rilevare l'eccezione e poi rilasciarlo? E se il metodo è privato?

EDIT: Mi dispiace di non aver detto che lancio eccezioni solo quando ci sono alcuni bug

    
posta arabum97 24.04.2017 - 11:58
fonte

4 risposte

4

In primo luogo, questa sarà un'opinione, così tante risposte ragionevoli saranno svalutate da coloro che hanno opinioni diverse. Secondo, sarà in qualche modo dipendente dalla lingua e dalla piattaforma: un approccio che dovrebbe essere leggermente migliore ma che è incredibilmente goffo nella lingua è un approccio sbagliato.

La scelta più importante è avere un piano comprensibile e comunicarlo. Probabilmente stai pensando a questi tipi di errori:

  • Hai chiamato la libreria in modo errato e vuoi darti il messaggio di errore corretto. Potresti scegliere di "emettere il messaggio di errore e crash" in quanto si tratta di un bug del tempo di sviluppo.
  • Una dipendenza ha passato un errore o ha risposto in modo errato. Ad esempio, la GUI si rifiuta di assegnare i colori. Dato che non puoi gestirlo, è sufficiente gorgogliare verso l'alto.
  • Si è verificato un valore di ritorno insolito. È un valore eccezionale, ad es. "La creatura non riesce a trovare il percorso verso il bersaglio" o "il percorso è troppo lungo" ma è ancora un ritorno noto e valido. Molte lingue funzionano meglio se questo si presenta come un'eccezione. L'utente della biblioteca può scegliere cosa ha senso per il gioco.

Ti consiglio di scegliere e documentare uno schema di denominazione per i problemi in modo che uno sviluppatore sappia quale tipo di eccezione viene trasmessa verso l'alto.

    
risposta data 24.04.2017 - 23:51
fonte
2

Should I catch every generic exceptions/ exceptions thrown by standard components (like lists,dictionaries,etc...) and then throw a contextualized exception?

Ho avuto un buon successo con questo approccio, ma assicurati di non distruggere la traccia dello stack. La tua eccezione avrà un InnerException (Java chiama queste "cause") che contiene l'eccezione originale.

Con il wrapping delle eccezioni lib standard in eccezioni specifiche del dominio si ottiene una certa flessibilità nei dettagli di implementazione senza rompere i contratti API. Supponiamo che tu consenta a IndexOutOfBoundsException di emergere dal tuo codice e nel client chiamante. Il cliente non ha altra scelta che prendere IndexOutOfBoundsException . Successivamente, si passa dall'interno utilizzando un array a un elenco. Ora il codice cliente sarà interrotto perché lo stesso errore genera un ElementNotFoundException . Se lo avessi impacchettato in un AwesomeLibException , la tua API sarebbe rimasta intatta e il client non avrebbe avuto un codice rotto automaticamente durante l'aggiornamento delle versioni della tua libreria.

Ora, alcuni sostengono che le eccezioni interne determinano ancora un'astrazione che perde. Probabilmente hanno ragione, ma per convenzione le eccezioni interne non fanno parte del contratto API e non devono essere ispezionate dal codice del cliente. Sono lì per aiutare nel debug della lib, non per il codice client da ispezionare e gestire direttamente.

    
risposta data 25.04.2017 - 23:52
fonte
2

Ci sono molte risposte basate sull'opinione, ma c'è una risposta su cui tutti dovrebbero assolutamente essere d'accordo:

If your library throws an exception, the user must catch it to handle it. Thus, the user's opinion about how you should throw exceptions is the right one.

Se ci si aspetta che il tuo utente approfondisca la tua implementazione ogni volta che si verifica un'eccezione per capire cosa è andato storto e per gestirlo, devi lanciare l'eccezione originale. Ora di solito questa è una supposizione sciocca. La maggior parte degli utenti non ha nemmeno il codice sorgente nelle loro librerie, tanto meno sapere come eseguirne il debug, ma il tuo programma potrebbe essere diverso. Se i tuoi utenti hanno una buona ragione per approfondire la tua biblioteca, l'involucro delle eccezioni potrebbe semplicemente mettersi in mezzo. Detto questo, è generalmente una cattiva forma per costringere l'utente ad essere a conoscenza dei dettagli di implementazione della libreria. Immagina se avessero una gestione delle eccezioni per un errore che potresti fare con un elenco, solo per scoprire che hai rifattorizzato la libreria per utilizzare gli array.

Potrebbe sorgere un altro caso se le eccezioni sono davvero degli errori: eccezioni che non sono mai destinate a essere gestite. Sono destinati ad abortire l'applicazione. Forse la tua eccezione nell'algoritmo che usa la lista mette la tua biblioteca in uno stato incoerente che non potrà mai più essere usato. Chiamerei quel design scadente, ma ci sono un sacco di motivi non di codice per creare strani prodotti nel mondo reale.

Personalmente, preferisco trattare l'eccezione come ultima conversazione tra i fossi con il mio utente. È dove la mia biblioteca non è riuscita a soddisfare le sue aspettative, e devo ammettere che le cose saranno difficili. In tal caso, provo a ripulire il più possibile (provo a riportare il sistema in uno stato coerente), quindi a generare un'eccezione personalizzata che è possibile provare a recuperare e recuperare. Se c'è la possibilità che i tuoi utenti vogliano approfondire la tua libreria, assicurati di fornire loro InnerException per conservare la traccia dello stack e le informazioni sulle eccezioni di cui hanno bisogno per farlo.

Ma in tutti i casi, l'opinione dell'utente è fondamentale. Crea un prodotto che gli utenti vorranno utilizzare, e il resto può sempre essere risolto in seguito. Crea un prodotto perfetto che gli utenti non utilizzeranno e non importa in che modo hai seguito le best practice.

    
risposta data 26.04.2017 - 00:11
fonte
-3

Dipende sempre da cosa farai ulteriormente con le eccezioni scoperte.

Parlando da un punto di vista di manutenzione del codice e di DEUMIDITA ', è consigliabile avere come un gestore di eccezioni globale, al livello più alto della tua applicazione. Ad esempio: Global.asax.

Da quel momento, puoi continuare a persistere eccezioni ed errori nel database per ispezionarli e correggerli un po 'di tempo e assicurarti che l'utente veda una bella pagina di errore formattata invece della pagina delle eccezioni predefinita.

    
risposta data 24.04.2017 - 13:00
fonte

Leggi altre domande sui tag