Quei messaggi sono per altri sviluppatori
Questi messaggi dovrebbero essere letti dagli sviluppatori per aiutarli a eseguire il debug dell'applicazione. Questo può assumere due forme:
Debug attivo. In realtà stai eseguendo un debugger mentre scrivi il codice e cerchi di capire cosa succede. In questo contesto, un'utile eccezione ti guiderà semplificando la comprensione di ciò che non funziona o suggerendo eventualmente una soluzione alternativa (sebbene sia facoltativa).
Debug passivo. Il codice viene eseguito in produzione e non riesce. L'eccezione viene registrata, ma ottieni solo il messaggio e la traccia dello stack. In questo contesto, un utile messaggio di eccezione ti aiuterà a localizzare rapidamente il bug.
Poiché tali messaggi vengono spesso registrati, significa anche che non dovresti includere lì informazioni sensibili (come chiavi private o password, anche se potrebbe essere utile eseguire il debug dell'app).
Ad esempio, il IOSecurityException
tipo di un'eccezione generata durante la scrittura di un file non è molto esplicito sul problema: è perché non abbiamo le autorizzazioni per accedere a un file? O forse possiamo leggerlo, ma non scrivere? O forse il file non esiste e non abbiamo i permessi per creare file lì? O forse è bloccato (si spera, il tipo di eccezione sarà diverso in questo caso, ma in pratica, i tipi a volte possono essere criptici). O forse Code Access Security ci impedisce di eseguire qualsiasi operazione di I / O?
Anziché:
IOSecurityException: il file è stato trovato ma l'autorizzazione a leggere il suo contenuto è stata negata.
è molto più esplicito. Qui, sappiamo immediatamente che le autorizzazioni sulla directory sono impostate correttamente (altrimenti, non saremo in grado di sapere che il file esiste), ma le autorizzazioni a livello di file sono problematiche.
Ciò significa anche che se non è possibile fornire ulteriori informazioni che non sono già nel tipo di eccezione, è possibile mantenere vuoto il messaggio. DivisionByZeroException
è un buon esempio in cui il messaggio è ridondante. D'altra parte, il fatto che la maggior parte delle lingue ti permetta di generare un'eccezione senza specificare il suo messaggio viene fatto per un motivo diverso: o perché il messaggio predefinito è già disponibile o perché verrà generato in seguito, se necessario (e la generazione di questo il messaggio è racchiuso nel tipo di eccezione, che ha perfettamente senso, parlando "OOPly" ).
Nota che per motivi tecnici (spesso prestazionali), alcuni messaggi finiscono per essere molto più criptici di quanto dovrebbero essere. .NET NullReferenceException
:
Il riferimento non impostato su un'istanza di un oggetto.
è un eccellente esempio di messaggio non utile. Un messaggio utile sarebbe:
Riferimento oggetto product
non impostato su un'istanza di un oggetto quando viene chiamato product.Price
.
Quei messaggi non sono per gli utenti finali!
Gli utenti finali non devono vedere i messaggi di eccezione. Mai. Sebbene alcuni sviluppatori finiscano per mostrare questi messaggi agli utenti, ciò porta a una scarsa esperienza utente e frustrazione. Messaggi come:
Il riferimento non impostato su un'istanza di un oggetto.
non significa assolutamente nulla per un utente finale e dovrebbe essere evitato a tutti i costi.
Lo scenario peggiore è avere un tentativo / cattura globale che genera l'eccezione per l'utente ed esce dall'app. Un'applicazione che ha a cuore i suoi utenti:
Gestisce le eccezioni in primo luogo. La maggior parte di essi può essere gestita senza disturbare l'utente. La rete non funziona? Perché non aspettare qualche secondo e riprovare?
Impedisce a un utente di condurre l'applicazione a un caso eccezionale. Se chiedi all'utente di inserire due numeri e dividere il primo per il secondo, perché dovresti consentire all'utente di inserire zero nel secondo caso per biasimarlo qualche secondo dopo? Che ne dici di evidenziare la casella di testo in rosso (con un utile suggerimento che dice che il numero dovrebbe essere diverso da zero) e disabilitare il pulsante di convalida fino a quando il campo rimane rosso?
Invita un utente a eseguire un'azione in un modulo che non è un errore. Non ci sono autorizzazioni sufficienti per accedere a un file? Perché non chiedere all'utente di concedere autorizzazioni amministrative o scegliere un altro file?
Se nient'altro funziona, mostra un errore utile e amichevole che è stato scritto appositamente per ridurre la frustrazione dell'utente, aiutare l'utente a capire cosa è andato storto e alla fine risolvere il problema, e anche aiutarlo a prevenire l'errore in futuro (se applicabile).
Nella tua domanda, hai suggerito di avere due messaggi in un'eccezione: uno tecnico per gli sviluppatori e uno per gli utenti finali. Sebbene questo sia un suggerimento valido in alcuni casi minori, la maggior parte delle eccezioni sono prodotte a un livello in cui è impossibile produrre un messaggio significativo per gli utenti. Prendi DivisionByZeroException
e immagina che non possiamo impedire che si verifichi l'eccezione e non possiamo gestirla da soli. Quando si verifica la divisione, il framework (dal momento che è il framework, e non il codice aziendale, che genera l'eccezione) sa quale sarà un messaggio utile per un utente? Assolutamente no:
Si è verificata la divisione per zero. [OK]
Invece, si può lasciare che generi l'eccezione e quindi catturarlo a un livello superiore in cui conoscevamo il contesto aziendale e potevamo agire di conseguenza al fine di aiutare effettivamente l'utente finale, mostrando così qualcosa di simile:
Il campo D13 non può avere il valore identico a quello nel campo E6, poiché la sottrazione di tali valori viene utilizzata come divisore. [OK]
o forse:
I valori riportati dal servizio ATP non sono coerenti con i dati locali. Ciò può essere causato dalla mancata sincronizzazione dei dati locali. Desideri sincronizzare le informazioni di spedizione e riprovare? [Si No]
Quei messaggi non sono per l'analisi
Non è previsto che i messaggi di eccezione vengano analizzati o utilizzati a livello di codice. Se si ritiene che il chiamante possa richiedere ulteriori informazioni, includerle nell'eccezione parallelamente al messaggio. Questo è importante perché il messaggio è soggetto a modifiche senza preavviso. Il tipo fa parte dell'interfaccia, ma il messaggio non lo è: non fare mai affidamento su di esso per la gestione delle eccezioni.
Immagina il messaggio di eccezione:
La connessione al server di memorizzazione nella cache è scaduta dopo aver atteso 500 ms. Aumentare il timeout o controllare il monitoraggio delle prestazioni per identificare un calo delle prestazioni del server. Il tempo medio di attesa per il server di memorizzazione nella cache era di 6 ms. per l'ultimo mese, 4 ms. per l'ultima settimana e 377 ms. per l'ultima ora.
Si desidera estrarre i valori "500", "6", "4" e "377". Pensa un po 'all'approccio che utilizzerai per eseguire l'analisi, e solo allora continua a leggere.
Hai l'idea? Grande.
Ora, lo sviluppatore originale ha scoperto un errore di battitura:
Connecting to the caching sever timed out after waiting [...]
dovrebbe essere:
↓
Connecting to the caching server timed out after waiting [...]
Inoltre, lo sviluppatore ritiene che il mese / settimana / un'ora non siano particolarmente rilevanti, quindi effettua anche una modifica aggiuntiva:
Il tempo medio di attesa per il server di memorizzazione nella cache era di 6 ms. per l'ultimo mese, 5 ms. per le ultime 24 ore e 377 ms. per l'ultima ora.
Cosa succede con l'analisi?
Invece di analizzare, potresti utilizzare le proprietà dell'eccezione (che possono contenere ciò che desideri, non appena i dati possono essere serializzati):
{
message: "Connecting to the caching [...]",
properties: {
"timeout": 500,
"statistics": [
{ "timespan": 1, "unit": "month", "average-timeout": 6 },
{ "timespan": 7, "unit": "day", "average-timeout": 4 },
{ "timespan": 1, "unit": "hour", "average-timeout": 377 },
]
}
}
Quanto è facile utilizzare questi dati ora?
A volte (come all'interno di .NET), il messaggio può anche essere tradotto nella lingua dell'utente (IMHO, tradurre quei messaggi è assolutamente sbagliato, dal momento che ogni sviluppatore dovrebbe essere in grado di leggere in inglese). L'analisi di tali messaggi è quasi impossibile.