I have an Asp.Net core 3.1 Web Api project in witch I have a lot of controllers.
almost in every controller I have a template like this:
public class SomeController:ControllerBase
{
//injecting my service
[HttpGet]
[Route("")]
public async Task<ActionResult> SomeMethod()
{
try
{
//Do some work
return Ok(somevalue);
}
catch(ServiceException ex)
{
return BadRequest(ex.Message);
}
catch
{
return BadRequest();
}
}
}
this template is implemented in almost all the controllers.
I want to delete try...catch statements and write a base class or something to handle this try...catch statements outside my controller.
something like this I reckon:
public async Task<ActionResult> SomeMethod()
{
//Do some work
return Ok(somevalue);
//if any exception of ServiceException type occured i want to
//return BadRequest with message and if not a BadRequest without message
}
I have heard something about Cross-Cutting Concerns but I don't know how to use them.
Do you have any Idea how can I do it?
CodePudding user response:
Absolutely agree, anything that has try/catch implemented everywhere is a code smell and there's a better way of doing things.
If you search for 'Global Exception Handling netcore' you'll find a lot of hits on this subject.
In general, let the exception propagate up the stack, preserve all the exception detail and let it be caught and handled by a Middleware. Probably a bit too much code to snippet into this answer, but here's decent article with a couple of different versions/examples available
https://jasonwatmore.com/post/2022/01/17/net-6-global-error-handler-tutorial-with-example
You'll notice returning responses from the middleware, and this is your opportunity to perform logging centrally as well - a single place to capture and log all your exception details.
CodePudding user response:
A simple approach:
public static ActionResult Try(Func<ActionResult> action)
{
try
{
return action();
}
catch (ServiceException ex)
{
return BadRequest(ex.Message);
}
catch
{
return BadRequest();
}
}
And you use like:
return Try(() => Ok(someValue));
Or
return Try(() =>
{
// Do something...
return new EmptyResult();
});