Reputation: 7960
I wrote an exception filter for my API to handle exceptions throw in the API:
using System;
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ApiExceptionFilter : ExceptionFilterAttribute {
public override void OnException(ExceptionContext context) {
// First, generate the status code based on the exception type
HttpStatusCode status = context.Exception switch {
UnauthorizedAccessException => HttpStatusCode.Unauthorized,
ArgumentException => HttpStatusCode.BadRequest,
MissingHeaderException => HttpStatusCode.BadRequest,
NotFoundException => HttpStatusCode.NotFound,
_ => HttpStatusCode.InternalServerError,
};
// Next, inject the status code and exception message into
// a new error response and set the result with it
context.Result = new JsonResult(new ErrorResponse {
StatusCode = status,
Message = context.Exception.Message
});
// Finally, call the base function
base.OnException(context);
}
}
This function intercepts exceptions as expected but the problem I'm having is that it always returns an OK response. How do I ensure that the response includes the exception message and that the response code is a non-200 value?
Upvotes: 3
Views: 2941
Reputation: 101
on .NET Core/.NET 6, we don't have ExceptionResult, but we can still achieve this goal. We can manually set the StatusCode for this request.
public override void OnException(ExceptionContext actionExecutedContext)
{
_logger.Error(actionExecutedContext.Exception);
actionExecutedContext.ExceptionHandled = true;
actionExecutedContext.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
actionExecutedContext.Result = new ObjectResult(new ErrorResponse()
{
StatusCode = (HttpStatusCode) StatusCodes.Status500InternalServerError,
Message = actionExecutedContext.Exception.Message,
});
base.OnException(actionExecutedContext);
}
Upvotes: 2
Reputation: 1629
Instead of returning a JsonResult
- which does not expose a status code property to be set - return an ExceptionResult
and set the status code like so:
context.Result = new ExceptionResult(context.Exception, true)
{ StatusCode = status };
If you still want to use your ErrorResponse object, just use an object result:
context.Result = new ObjectResult(new ErrorResponse {
StatusCode = status,
Message = context.Exception.Message
})
// set status code on result
{ StatusCode = status };
Upvotes: 5