Home > Back-end >  How to set custom exception with status code
How to set custom exception with status code

Time:09-21

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

  1. 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;
            }
        }
    }
    
  2. 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>();
  • Related