Skip to content

Instantly share code, notes, and snippets.

@ankitvijay
Last active April 20, 2021 23:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ankitvijay/168c41f3abb3e817375be05e7b2e7083 to your computer and use it in GitHub Desktop.
Save ankitvijay/168c41f3abb3e817375be05e7b2e7083 to your computer and use it in GitHub Desktop.
using System;
public interface IExceptionHandler
{
public Error HandleException(Exception exception);
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using FluentValidation;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
public class ExceptionHandler : IExceptionHandler
{
private readonly ILogger<ExceptionHandler> _logger;
private readonly IHostEnvironment _environment;
public ExceptionHandler(ILogger<ExceptionHandler> logger,
IHostEnvironment environment)
{
_logger = logger;
_environment = environment;
}
public Error HandleException(Exception exception)
{
var error = exception switch
{
ValidationException validationException => HandleValidationException(validationException),
DomainException domainException => HandleDomainException(domainException),
ResourceNotFoundException resourceNotFoundException => HandleResourceNotFoundException(resourceNotFoundException),
UnauthorizedException unauthorizedException => HandleUnauthorizedException(unauthorizedException),
_ => HandleUnhandledExceptions(exception)
};
if (_environment.IsDevelopment())
{
error.Exception = exception.ToString();
}
return error;
}
private Error HandleResourceNotFoundException(ResourceNotFoundException resourceNotFoundException)
{
_logger.LogInformation(resourceNotFoundException, resourceNotFoundException.Message);
return new Error
{
Title = resourceNotFoundException.Message,
StatusCode = HttpStatusCode.NotFound,
};
}
// ValidationException from FluentValidation
private Error HandleValidationException(ValidationException validationException)
{
_logger.LogInformation(validationException, validationException.Message);
var error = new Error
{
Title = validationException.Message,
StatusCode = HttpStatusCode.BadRequest
};
if (validationException.Errors != null && validationException.Errors.Any())
{
error.Entries = new List<ErrorEntry>();
error.Entries.AddRange(validationException.Errors.Select(validationError =>
new ErrorEntry
{
Code = validationError.ErrorCode,
Title = validationError.ErrorMessage,
Source = validationError.PropertyName
}));
}
return error;
}
private Error HandleDomainException(DomainException domainException)
{
_logger.LogInformation(domainException, domainException.Message);
return new Error
{
Title = domainException.Message,
StatusCode = HttpStatusCode.BadRequest
}
}
private Error HandleUnauthorizedException(UnauthorizedException unauthorizedException)
{
_logger.LogInformation(unauthorizedException, unauthorizedException.Message);
return new Error
{
Title = unauthorizedException.Message,
StatusCode = HttpStatusCode.Unauthorized
};
}
private Error HandleUnhandledExceptions(Exception exception)
{
_logger.LogError(exception, exception.Message);
return new Error
{
Title = "An unhandled error occurred while processing this request",
StatusCode = HttpStatusCode.InternalServerError
};
}
}
using System;
using System.Net.Mime;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
public class ApplicationExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly IExceptionHandler _exceptionHandler;
private readonly ILogger<ApplicationExceptionMiddleware> _logger;
public ApplicationExceptionMiddleware(
RequestDelegate next,
IExceptionHandler exceptionHandler,
ILogger<ApplicationExceptionMiddleware> logger)
{
_next = next;
_exceptionHandler = exceptionHandler;
_logger = logger;
}
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch (Exception ex)
{
var error = _exceptionHandler.HandleException(ex);
if (!httpContext.Response.HasStarted)
{
httpContext.Response.Clear();
httpContext.Response.ContentType = MediaTypeNames.Application.Json;
httpContext.Response.StatusCode = (int) errorDocument.StatusCode;
await httpContext.Response.WriteAsync(JsonSerializer.Serialize(
errorDocument));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment