I'm writing a reusable library, and I'm looking for a way to handle the exceptions that might occur during the processing. For example, I have the following class:
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
}
}
How to handle the DbException
and FileException
so that:
- the exception contract of
IObjectFetcher.GetObject
doesn't get too complex and can allow different implementations - there's a way to access the underlying cause of the exception, like a failed database connection or a missing file
- there's a way to differentiate between the
DbException
caused by looking up a file name and theDbException
caused by retrieving aFrob
- it's possible to attach the exception metadata like the object ID and the file name in a structured way, eg. to extract exception message templates into a resource file
It seems to me that I should create custom exceptions for each step of the process (with the InnerException
being either the DbException
or the FileException
), and then I have two ways of approaching the problem - either have those custom exceptions inherit from a single base class, or have them wrapped by a single exception class. Which approach is correct? Or should I simplify it further?