I'm able to get error message through my custom exception class, but it seems it always returning 500 status code.
How can I set the status code using my custom exception class?
this is the app flow:
Service:
throw new UCodeException("Already exist", StatusCodes.Status409Conflict);
UCodeException:
public class UCodeException : UException
{
public override int StatusCode { get; }
public UCodeException(string error, int statusCode) : base(error)
{
StatusCode = statusCode;
}
public UCodeException(string[] errors, int statusCode) : base(errors)
{
StatusCode = statusCode;
}
}
UException:
public abstract class UException : Exception
{
public string[] Errors { get; }
public abstract int StatusCode { get; }
protected UException(string error) : base(error)
{
Errors = new []{error};
}
protected UException(string[] errors)
{
Errors = errors;
}
}
CodePudding user response:
You can achieve it with Filter
- Create an action filter named
HttpResponseExceptionFilter
:public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter { public void OnActionExecuting(ActionExecutingContext context) { } public void OnActionExecuted(ActionExecutedContext context) { if (context.Exception is UCodeException exception) { context.Result = new ObjectResult(exception.Errors) { StatusCode = exception.StatusCode, }; context.ExceptionHandled = true; } } }
- In
Startup.ConfigureServices
, add the action filter to the filters collection:services.AddControllers(options => options.Filters.Add(new HttpResponseExceptionFilter()));
Or write custom exception middleware. Create class named ExceptionMiddleare
:
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
public ExceptionMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
if (ex is HttpResponseException exception)
{
context.Response.StatusCode = exception.StatusCode;
}
}
}
}
In Startup.Configure
add the middleware (before app.UseEndpoints
):
app.UseMiddleware<ExceptionMiddleware>();