Skip to content

Instantly share code, notes, and snippets.

@admir-live
Created August 30, 2023 09:18
Show Gist options
  • Save admir-live/d9452fa8755d122b5b86212dba666609 to your computer and use it in GitHub Desktop.
Save admir-live/d9452fa8755d122b5b86212dba666609 to your computer and use it in GitHub Desktop.
Example of GlobalHttpExceptionFilter with BadRequest
public class GlobalHttpExceptionFilter : ExceptionFilterAttribute
{
private readonly ILogger<GlobalHttpExceptionFilter> _exceptionLogger;
private readonly Dictionary<Type, Action<ExceptionContext, Exception>> _exceptionHandlers;
public GlobalHttpExceptionFilter(ILogger<GlobalHttpExceptionFilter> exceptionLogger)
{
_exceptionLogger = exceptionLogger ?? throw new ArgumentNullException(nameof(exceptionLogger));
_exceptionHandlers = new Dictionary<Type, Action<ExceptionContext, Exception>>
{
{ typeof(BadRequestException), HandleBadRequestException },
};
}
public override void OnException(ExceptionContext context)
{
LogError(context);
var exceptionType = context.Exception.GetType();
if (_exceptionHandlers.ContainsKey(exceptionType))
{
_exceptionHandlers[exceptionType].Invoke(context, context.Exception);
}
else
{
HandleGenericException(context);
}
}
private void LogError(ExceptionContext context)
{
_exceptionLogger.LogError(new EventId(context.Exception.HResult), context.Exception, context.Exception.Message);
}
private void HandleBadRequestException(ExceptionContext context, Exception exception)
{
var validationException = exception as BadRequestException;
SetErrorResponse(context, StatusCodes.Status400BadRequest, "DomainValidations", validationException.Message);
}
private void HandleGenericException(ExceptionContext context)
{
SetErrorResponse(context, StatusCodes.Status500InternalServerError, "Message", context.Exception.Message);
}
private void SetErrorResponse(ExceptionContext context, int statusCode, string errorType, string errorMessage)
{
var problemDetails = BuildProblemDetails(context, statusCode, errorType, errorMessage);
context.Result = statusCode == StatusCodes.Status400BadRequest
? new BadRequestObjectResult(problemDetails)
: new ObjectResult(problemDetails) { StatusCode = statusCode };
context.HttpContext.Response.StatusCode = statusCode;
}
private ValidationProblemDetails BuildProblemDetails(ExceptionContext context, int statusCode, string errorType, string errorMessage)
{
return new ValidationProblemDetails
{
Instance = context.HttpContext.Request.Path,
Status = statusCode,
Detail = "Please refer to the errors property for additional details.",
Errors = { { errorType, new[] { errorMessage } } }
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment