Sto scrivendo una libreria riutilizzabile e sto cercando un modo per gestire le eccezioni che potrebbero verificarsi durante l'elaborazione. Ad esempio, ho la seguente classe:
public interface IObjectFetcher
{
public IObject GetObject(int objectId);
}
public class WidgetFetcher : IObjectFetcher
{
public IObject GetObject(int objectId)
{
var fileName = DetermineWidgetFileName(objectId);
var widget = GetWidgetFromFile(fileName);
widget.Frob = GetWidgetFrob(objectId);
return widget;
}
private string DetermineWidgetFileName(int widgetId)
{
return someExternalDbService.GetFileNameForWidget(widgetId); //throws DbException
}
private Widget GetWidgetFromFile(string fileName)
{
return someExternalFileService.GetWidgetFromFile(fileName); //throws FileException
}
private Frob GetFrobForWidget(int widgetId)
{
return someExternalDbService.GetFrobForWidget(widgetId); //throws DbException
}
}
Come gestire DbException
e FileException
in modo che:
- il contratto di eccezione di
IObjectFetcher.GetObject
non diventa troppo complesso e può consentire implementazioni diverse - c'è un modo per accedere alla causa sottostante dell'eccezione, come una connessione al database fallita o un file mancante
- c'è un modo per distinguere tra
DbException
causato dalla ricerca di un nome file e ilDbException
causato dal recupero di unFrob
- è possibile allegare i metadati delle eccezioni come l'ID oggetto e il nome del file in modo strutturato, ad es. per estrarre i modelli di messaggi di eccezione in un file di risorse
Mi sembra che dovrei creare eccezioni personalizzate per ogni fase del processo (con InnerException
come DbException
o FileException
), e quindi ho due modi per affrontare il problema - o fare in modo che tali eccezioni personalizzate ereditino da una singola classe di base, o che siano racchiuse da una singola classe di eccezioni. Quale approccio è corretto? O dovrei semplificarlo ulteriormente?