Reputation: 15175
I am taksed to introduce exception logging in a layer of middleware. From top to bottom of this middleware the calls are as follows:
//In layer C
public async Task<List<Foo>> GetFoo(GetFooRequest request)
{
return await _repository.GetFooAsync(request);
}
//In layer D
public async Task<List<Foo>> GetFooAsync(GetFooRequest request)
{
return await _context.Foo.Where(x=> x.FooId=request.FooID).ToListAsync();
}
I would like to log in Layer C, however, Task returns a System.Void, as such the compiler complains about the code below. I understand why the code below fails but I am having problems finding a solution pattern or practice of logging in layer C.
//In layer C
public async Task<List<Foo>> GetFoo(GetFooRequest request)
{
try
{
return await _repository.GetFooAsync(request);
}
catch(Exception e)
{
base.LogException(e) //<- Not all code paths return a value
}
}
Is there a way I can create a class that Invokes methods and do logging there, such as return await LogInvoker.Invoke(_repository.GetFooAsync...)
? Or does this require refactoring the current flow between the layers?
Upvotes: 0
Views: 471
Reputation: 62472
You've got to do something at the end of the catch
block. You mention in the question comments that you'd be prepared to return an empty list if something goes wrong:
public async Task<List<Foo>> GetFoo(GetFooRequest request)
{
try
{
return await _repository.GetFooAsync(request);
}
catch(Exception e)
{
base.LogException(e);
return new List<Foo>();
}
}
or rethrow the exception, if that makes sense to your application:
public async Task<List<Foo>> GetFoo(GetFooRequest request)
{
try
{
return await _repository.GetFooAsync(request);
}
catch(Exception e)
{
base.LogException(e);
throw;
}
}
Upvotes: 1