I've got a number of WebService methods that all include some very boilerplate code of wrapping the actual work in a try/catch/finally and performing the same tasks in the catch/finally. So as a way to encapsulate all of the shared catch/finally stuff I wrote a simple generic.
This works and really eliminates a bunch of repetitive code but feels klunky, and the syntax is very obtuse. Every time I come back to this my brain gets twisted trying to figure it out (a clear sign it is not a good design). I'm looking for feedback on whether this is a crazy thing to do, and if there is a better way to approach it.
Here is my template:
public delegate T2 RestfulServiceRequest<T1, T2>(T1 req);
static class RestfulService
{
public static T2 ExceptionHandler<T1, T2>(RestfulServiceRequest<T1, T2> serviceCall, T1 req)
{
if (req == null)
throw new BadRequestException(new ArgumentNullException("Invalid or missing request object"));
try
{
return serviceCall(req);
}
catch (RestfulException e)
{
// log it and rethrow
Logger.Write(e);
throw;
}
catch (Exception e)
{
Logger.Error(e);
// wrap in a consistent exception for propagation back to caller
throw new InternalServerException(e);
}
finally
{
Logger.Debug("Complete");
}
}
}
}
And here is a usage of it:
public class Initialization : IInitialization
{
// MyMethod thas uses the template
public ApplianceInitResp CreateApplianceServer(ApplianceInitReq req)
{
return RestfulService.ExceptionHandler<ApplianceInitReq, ApplianceInitResp>(delegate(ApplianceInitReq x)
{
// do some work
return new ApplianceInitResp();
}, req);
}
}
}