Stiamo discutendo il modo migliore per gestire gli errori nelle chiamate a un metodo.
Abbiamo un modello di credito in cui consentiamo agli utenti di detrarre crediti per determinate azioni. Vorremmo effettuare una chiamata a:
User.DeductCredits(10);
Quindi il metodo Deduct controllerà cose come
- L'utente esiste?
- L'utente è attivo?
- L'utente ha almeno 10 crediti?
In caso contrario, questo risultato dovrebbe fallire.
Al momento stiamo scrivendo questo come una libreria di classi, ma proviamo a tenerlo aperto per convertirci in un servizio web in futuro. Le opzioni che abbiamo discusso finora sono:
- Genera un'eccezione quando si verifica un errore.
- Crea un nuovo oggetto risultato che T abbia il tipo di dati attesi e avvolgendolo con un codice di stato e un messaggio.
Non ci piaceva l'opzione n. 1, perché il codice per chiamare i crediti di deduzione sarebbe simile a:
try
{
user.DeductCredits(10);
}
catch(InvalidUserException e)
{
}
catch(InactiveUserException e)
{
}
catch(CreditBalanceException e)
{
}
Inoltre, se trasformiamo questo in un servizio, non possiamo imporre eccezioni all'utente.
Il motivo principale per cui non è piaciuta l'opzione n. 2 è che sembrava che restituisse più dati di quelli di cui abbiamo bisogno. Ad esempio:
var address = user.GetMailAddress();
Ora l'indirizzo ha il codice di stato e il messaggio, oltre a una proprietà dati o una proprietà valore. Quindi, per ottenere la città, avresti codice come:
if(!address.HasError)
state = address.Data.State;
al contrario di:
state = address.State;
Quindi esiste una best practice per questo tipo di situazione? Un'opzione è davvero migliore dell'altra?