Eccezioni "Errore di programmazione" - Il mio approccio è corretto?

9

Attualmente sto cercando di migliorare il mio uso delle eccezioni e ho trovato l'importante distinzione tra le eccezioni che indicano errori di programmazione (ad esempio qualcuno ha passato null come argomento, o chiamato un metodo su un oggetto dopo che è stato eliminato) e quelle che indicano un errore nell'operazione che non è l'errore del chiamante (ad esempio un'eccezione I / O).

In che modo questi due tipi di eccezioni dovrebbero essere trattati in modo diverso? Pensi che le eccezioni di errore debbano essere esplicitamente documentate, o è sufficiente documentare le condizioni preliminari rilevanti? E puoi omettere la documentazione di una precondizione o di un'eccezione di errore se dovrebbe essere ovvia (ad esempio, ObjectDisposedException quando si chiama un metodo su un oggetto disposto)

    
posta Medo42 19.11.2012 - 12:23
fonte

5 risposte

2

Penso che tu sia sulla strada giusta. Non ha senso gettare, catturare o documentare tutte le eccezioni potenzialmente lanciabili. Vi sono periodi in cui la rigidità del prodotto richiede un grado più elevato di utilizzo e documentazione delle eccezioni (ad esempio alcuni aspetti critici per la sicurezza di un sistema).

La strategia di essere più difensivi, usando concetti contrattuali per identificare le precondizioni (e le postcondizioni) su chiamanti soprattutto downstream (ad esempio qualsiasi cosa che assomigli a un membro pubblico o protetto) sarà spesso più efficace e più flessibile. Questo vale non solo per l'implementazione, ma per la documentazione. Se gli sviluppatori sanno cosa si aspetta, sono più propensi a seguire le regole e meno probabilità di confondersi o usare impropriamente il codice che hai scritto.

Alcune delle cose comuni che dovrebbero essere documentate includono il caso di parametri null. Spesso c'è una conseguenza per il loro uso che porta il risultato a qualcosa che normalmente non ci si aspetterebbe, ma è permesso e utilizzato per una serie di motivi, a volte per la flessibilità. Come consumatore di un membro che ha parametri che consentono valori null o altri valori speciali non razionali (come il tempo negativo o le quantità negative), mi aspetto di vederli identificati e spiegati.

Per i parametri non nulli, come consumatore di un membro pubblico o protetto, desidero sapere che null non è consentito. Voglio sapere qual è l'intervallo valido di valori nel contesto dato. Voglio conoscere le conseguenze dell'utilizzo di valori che sono al di fuori dell'intervallo normale, ma sono validi in un contesto di chiamata diverso (ad esempio il valore del tipo è generalmente valido per qualsiasi operazione, ma non qui - come un parametro booleano che non Non aspettarti il falso come valore valido.

Per quanto riguarda la piattaforma, o altrimenti le interfacce ben note, non penso che tu debba andare agli estremi nel documentarlo. Tuttavia, perché hai l'opportunità come sviluppatore di variare l'implementazione da qualsiasi guida di piattaforma, prendendo nota di quanto segue che la guida può avere un valore.

Specifici per IDisposable, spesso le implementazioni di questa interfaccia offrono un metodo alternativo che è preferito rispetto al processo di smaltimento esplicito. In questi casi, evidenzia il metodo preferito e nota che l'eliminazione esplicita non è preferita.

    
risposta data 19.11.2012 - 13:25
fonte
2

Ecco i miei pensieri. Nota che non sono troppo sicuro che questo sia il modo migliore per andare, ed è per questo che ho creato questa domanda in primo luogo.

Per quanto comprendo, non ha molto senso che un chiamante immediato gestisca effettivamente le eccezioni degli errori di programmazione, dovrebbe invece assicurare che le precondizioni siano soddisfatte. Solo i gestori di eccezioni "esterni" ai limiti delle attività devono catturarli, in modo che possano mantenere il sistema in esecuzione se un'attività non riesce.

Al fine di garantire che il codice client riesca a catturare in modo pulito le eccezioni di "errore" senza rilevare per errore le eccezioni di errore, creo le mie proprie classi di eccezione per tutte le eccezioni di errore ora e le documento nei metodi che le generano. Li farei controllare le eccezioni in Java.

Fino a poco tempo fa, ho provato a documentare tutte le eccezioni che un metodo poteva lanciare, ma a volte crea un elenco non ordinato che deve essere documentato in ogni metodo fino alla catena di chiamata finché non si può dimostrare che l'errore non si verificherà. Invece, ora documenterò le precondizioni nella descrizione del sommario / parametro e non dirò nemmeno cosa succede se non vengono soddisfatte. L'idea è che le persone non dovrebbero cercare di cogliere queste eccezioni in modo esplicito comunque, quindi non c'è bisogno di documentare i loro tipi.

Per documentare le condizioni preliminari, affermare l'ovvio crea solo inutili confusione - se passare null a un metodo non ha senso, il chiamante deve aspettarsi un'eccezione se passa comunque null, anche se questo non è documentato. Lo stesso vale per il caso di ObjectDisposedException: questa interfaccia è così ampiamente utilizzata che qualcuno che chiama Dispose sarebbe consapevole della responsabilità di garantire che nessuno continui a utilizzare l'oggetto.

    
risposta data 19.11.2012 - 13:16
fonte
1

Una ragionevole regola pratica:

  1. Cattura qualsiasi eccezione che puoi correggere.
  2. Cattura, commenta e ripassa qualsiasi eccezione che non puoi correggere, ma puoi dire qualcosa di utile su.
  3. Non rilevare alcuna eccezione che non puoi elaborare o diagnosticare meglio di quanto non verrà elaborato in modo predefinito.

Potresti voler avere un gestore di eccezioni non fatali di livello superiore per intercettare tutto ciò che non può essere gestito di seguito per cercare di impedire che la tua applicazione cada, ma questo dipenderà strongmente dalla tua particolare applicazione. Ad esempio, le applicazioni iOS preferiscono intrappolare il più possibile; un'app della riga di comando può essere perfettamente OK se non intercetta quasi nessuna eccezione.

    
risposta data 29.04.2014 - 23:16
fonte
0

Anche Java non "documenta" tutte le eccezioni. Nonostante il requisito che ogni throw n sia menzionata in una clausola throws , qualsiasi riga di codice può lanciare un RuntimeException senza doverlo dichiarare nella firma del metodo.

    
risposta data 20.11.2012 - 02:19
fonte
0

Il modo standard per farlo è con l'approccio java. Gli errori di programmazione dovrebbero essere eccezioni non controllate e non dovrebbero essere catturati per garantire un errore veloce. Gli errori del contratto sono eccezioni controllate e devono essere gestiti in modo appropriato dal client.

    
risposta data 20.11.2012 - 05:14
fonte

Leggi altre domande sui tag