Immaginiamo di avere un servizio CustomerService :
public class CustomerService
{
public Customer GetCustomer(string customerName)
{
if(string.IsNullOrWhiteSpace(customerName))
throw new ArgumentNullException(nameof(customerName));
try
{
var customer = customerRepository.GetByName(customerName);
return customer;
}
catch(Exception ex)
{
_logger.Error(ex);
throw;
}
}
}
Questo servizio è utilizzato in un controller MyController :
public class MyController : Controller
{
/* Properties */
public ActionResult CustomerStuff(string customerName)
{
try
{
var customer = _customerService.GetCustomer(customerName);
return View(customer);
}
catch (Exception ex)
{
// Redirect to error page, etc...
}
}
}
Il problema con questo è che nascondo possibile ArgumentNullException che è probabilmente causato da un bug nel mio codice. Non mi aspetto mai che passi nulla da null a GetCustomer , ma catch(Exception) in MyController nasconde questa eccezione con il resto delle eccezioni. D'altra parte, in produzione, desidero reindirizzare gli utenti se qualcosa va storto in CustomerService , perché ad es. si è verificato un timeout di connessione.
Come si può risolvere questo problema senza tonnellate di codice, come ad esempio:
try
{
}
catch (Exception ex) when (!(ex is ArgumentNullException))
{
// handle timeouts, network availability, etc..
}
Una possibile soluzione che riesco a vedere è la creazione di un'eccezione personalizzata, ad esempio ServiceException e il lancio all'interno di try/catch in GetCustomer metodo. C'è qualche altra tecnica che è forse più comune?