In questa domanda più recente ho sottolineato che le eccezioni non dovrebbero contenere alcun messaggio. A mio parere, il fatto che lo facciano è un enorme equivoco. Quello che sto proponendo è che
The "message" of the exception is the (fully qualified) class name of the exception.
Un'eccezione dovrebbe contenere all'interno delle proprie variabili membro quanti più dettagli possibili su esattamente cosa è successo; per esempio, un IndexOutOfRangeException
dovrebbe contenere il valore dell'indice che è stato trovato non valido, così come i valori superiore e inferiore che erano validi nel momento in cui l'eccezione è stata lanciata. In questo modo, usando la reflection puoi avere un messaggio costruito automaticamente che si legge così: IndexOutOfRangeException: index = -1; min=0; max=5
e questo, insieme alla traccia dello stack, dovrebbe essere tutte le informazioni oggettive di cui hai bisogno per risolvere il problema. La formattazione in un messaggio carino come "indice -1 non era tra 0 e 5" non aggiunge alcun valore.
Nel tuo particolare esempio, la classe NodePropertyNotFoundException
conterrà il nome della proprietà che non è stata trovata e un riferimento al nodo che non contiene la proprietà. Questo è importante: dovrebbe non contenere il nome del nodo; dovrebbe contenere un riferimento al nodo attuale. Nel vostro caso particolare, questo potrebbe non essere necessario, ma è una questione di principio e un modo di pensare preferito: la preoccupazione principale quando si costruisce un'eccezione è che deve essere utilizzabile dal codice che potrebbe catturarlo. L'usabilità da parte dell'uomo è un'importante, ma solo una preoccupazione secondaria.
Questo si prende cura della situazione molto frustrante alla quale potresti essere stato testimone in qualche momento della tua carriera, in cui potresti aver colto un'eccezione contenente informazioni vitali su ciò che accadeva nel testo del messaggio, ma non all'interno delle sue variabili membro , quindi hai dovuto eseguire il parsing di stringhe del testo per capire cosa è successo, sperando che il testo del messaggio rimanga lo stesso nelle versioni future del livello sottostante e pregando che il testo del messaggio non sia in qualche lingua straniera quando il tuo programma viene eseguito in altri Paesi.
Naturalmente, poiché il nome classe dell'eccezione è il messaggio dell'eccezione (e le variabili membro dell'eccezione sono i dettagli specifici), ciò significa che sono necessarie molte e molte eccezioni per trasmettere tutti i diversi messaggi, e va bene.
Ora, a volte, mentre scriviamo il codice, ci imbattiamo in una situazione errata per cui vogliamo semplicemente codificare rapidamente un'istruzione throw
e continuare a scrivere il nostro codice invece di dover interrompere ciò che stiamo facendo per creare una nuova classe di eccezione in modo che possiamo lanciarlo proprio lì. Per questi casi, ho una classe GenericException
che in effetti accetta un messaggio di stringa come parametro di costruzione, ma il costruttore di questa classe di eccezioni è decorato con un grande, enorme e luminoso commento FIXME XXX TODO
che afferma che ogni singolo l'istanziazione di questa classe deve essere sostituita con un'istanza di alcune classi di eccezioni più specializzate prima che il sistema software venga rilasciato, preferibilmente prima che il codice venga eseguito.