본문 바로가기

c#/ASP.NET CORE

ASP.NET CORE 전역 에러 처리 Global Error Exception

asp.net core에서는 미들웨어를 통해서 에러를  전역에서 관리할 수 있습니다.

그냥 일반적인 try catch문을 사용해도 무방하지만 이러한 방법을 쓰면 에러를 중앙에서 관리하기 때문에 더 에러 처리에 대한 프로세스 관리를 쉽게 할 수 있습니다. 

구성 방법은 아래와 같습니다.

public class NotFoundException : ApplicationException
 {
     public NotFoundException(string name, object key) : base($"{name}({key}) was not found")
     {
 
     }
 }

위처럼 오류가 날만한 부분에 생성할 Exception 클래스를 하나 생성하고 ApplicationException 클래스를 상속받습니다.

public class ExceptionMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<ExceptionMiddleware> _logger;
 
        public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger)
        {
            this._next = next;
            this._logger = logger;
        }
 
        public async Task InvokeAsync(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Something Went Wrong in the {context.Request.Path}");
                await HandleExceptionsAsync(context, ex);
            }
        }
 
        private Task HandleExceptionsAsync(HttpContext context, Exception ex)
        {
            context.Response.ContentType = "application/json";
            HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
 
            var errorDetails = new ErrorDetails
            {
                ErrorType = "Failure",
                ErrorMessage = ex.Message,
            };
 
            switch (ex)
            {
                case NotFoundException notFoundException:
                    statusCode = HttpStatusCode.NotFound;
                    errorDetails.ErrorType = "Not Found";
                    break;
                default:
                    break;
            }
 
            string response = JsonConvert.SerializeObject(errorDetails);
            context.Response.StatusCode = (int)statusCode;
 
            return context.Response.WriteAsync(response);
        }
    }
 
    public class ErrorDetails
    {
        public string ErrorType { get; set; }
 
        public string ErrorMessage { get; set; }
    }

위처럼 Exception을 처리할 미들웨어를 만드는데 이때 InvokeAsync의 try catch에서 제대로 처리되지 못하고 에러가 뜨게되면 catch 문의 HandleExceptionAysnc에서 Exception의 종류에 따라서 오류 반환을 지정 할 수 있습니다.

[HttpGet("{id}")]//파라미터값 id 받아야함 템플릿을 지우면 엔드포인트가 같아져서 충돌남
       public async Task<ActionResult<CountryDto>> GetCountry(int id)
       {
           var country = await _countriesRepository.GetDetails(id);
 
           if (country == null)
           {
               throw new NotFoundException(nameof(GetCountry), id);
               //_logger.LogWarning($"Record found in {nameof(GetCountry)}");
               //return NotFound();
           }
 
           var countryDto = _mapper.Map<CountryDto>(country);
 
           return Ok(countryDto);
       }

위에서 만든 NotFoundException클래스를 thorwe뒤에 생성하여 전역 처리를 합니다.

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
 
app.UseMiddleware<ExceptionMiddleware>();
app.UseSerilogRequestLogging(); //http 요청에 대한 로깅
 
app.UseHttpsRedirection();

 마지막으론 program.cs에서 UseMiddleware를 통해서 ExceptionMiddleware를 설정하여 미들웨어를 등록해주면

메서드에서 throw를 발생시키면 NotFoundException에 서 공통적으로 처리를 할 수 있습니다.

 

'c# > ASP.NET CORE' 카테고리의 다른 글

ASP.NET CORE HTTP health Check  (0) 2024.05.20
ASP.NET CORE AutoMapper 사용법  (0) 2024.03.05