C
C#2y ago
Bunda

❔ How to properly handle exceptions between API controller and service layer?

I'm creating an API and I'm having trouble figuring out how to properly catch errors between my service layer and controller. Could someone take a look at my current code and give me some advice? Useful docs or tutorials are also greatly appreciated. To better understand the controller, this the controller route: /api/v1/identity-users/{userRefId:guid}/risks This is my current controller: https://pastebin.com/Cg4CJ0QE My service: https://pastebin.com/KVaN3nYR
11 Replies
nahr
nahr2y ago
Hi, maybe an exception middleware can help you to centralize and make your error handling cleaner
artya
artya2y ago
Since you asked for useful docs here's .NET Core Web API docs on Error Handling: https://learn.microsoft.com/en-us/aspnet/core/web-api/handle-errors?view=aspnetcore-7.0
Handle errors in ASP.NET Core web APIs
Learn about error handling with ASP.NET Core web APIs.
artya
artya2y ago
Other than that I'd say catch errors inside of your service too Instead of returning null you could throw a NullArgumentException
Bunda
BundaOP2y ago
Hi, I've been reading about IExceptionFilter which can be configured globally. However it looks like I then have to return my own responses instead of using the ValidationProblem / ProblemDetail response, which I really like. Any idea on how that would work?
nahr
nahr2y ago
Here is a example of a custom middleware
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionMiddleware> _logger;

public ExceptionMiddleware(ILogger<ExceptionMiddleware> logger, RequestDelegate next)
{
_logger = logger;
_next = next;
}

public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
_logger.LogError(ex);
await HandleExceptionAsync(context, ex);
}
}

private static Task HandleExceptionAsync(HttpContext context, Exception ex)
{
// do ur stuff
}
}
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionMiddleware> _logger;

public ExceptionMiddleware(ILogger<ExceptionMiddleware> logger, RequestDelegate next)
{
_logger = logger;
_next = next;
}

public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
_logger.LogError(ex);
await HandleExceptionAsync(context, ex);
}
}

private static Task HandleExceptionAsync(HttpContext context, Exception ex)
{
// do ur stuff
}
}
Bunda
BundaOP2y ago
Thanks for the info. I'm not sure but it is my understanding that when using nullable in a project I should not throw exceptions when not needed because of the performance hit that comes with it. Is that correct?
artya
artya2y ago
Ah I read over the GetUserByRefId call
Bunda
BundaOP2y ago
A filter like that would be great! Any idea how would I implement this part using the middleware? I feel like I'm repeating myself over and over with the error handling..
var message = e.InnerException?.Message ?? e.ToString();

_logger.LogWarning("Failed to create RiskyUser with userRefId {userRefId}: {exception}", userRefId, message);
ModelState.AddModelError("UniqueConstraintException", message);

return ValidationProblem(title: "Bad Request", statusCode: 400);
var message = e.InnerException?.Message ?? e.ToString();

_logger.LogWarning("Failed to create RiskyUser with userRefId {userRefId}: {exception}", userRefId, message);
ModelState.AddModelError("UniqueConstraintException", message);

return ValidationProblem(title: "Bad Request", statusCode: 400);
Bunda
BundaOP2y ago
Thanks! I will try and hack something together
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server