예외 필터링에 'is not' 연산자를 활용하세요! | Steven Giesel

예외 필터링과 함께 ‘is not’ 연산자를 사용하여 C#에서 오류 처리를 간소화하고 개선할 수 있다는 사실을 알고 계셨나요?

이 짧은 블로그 게시물에서 그 사용법을 보여드리겠습니다.

문제

다음과 같은 함수가 있다고 가정해 보겠습니다.

private async Task ListenAndHandleMessageAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        var result = _subscriberService.Consume(stoppingToken);
        try
        {
            await ProcessMessagesAsync(result, stoppingToken);
        }
        catch (Exception e)
        {
            Logger.LogError(e, "There was an error while processing {Message}.", typeof(TMessage).Name);
        }
    }
}

제 경우에는 카프카 브로커의 메시지를 수신하는 BackgroundService 입니다. 모든 예외를 처리하고 로깅하지만(여기서는 단순화된 예제입니다), 취소 요청이 있으면 어떻게 될까요? 글쎄요, 저희도 예외를 기꺼이 받아들입니다. 하지만 저는 그러고 싶지 않습니다. 그렇다면 이 문제를 어떻게 해결할 수 있을까요? System.Exception 대신 좀 더 구체적인 예외를 잡을 수도 있지만, 그렇게 하면 피하고 싶은 매우 반복적인 코드가 될 수도 있고, catch 블록 안에 if (e.GetType() == typeof(OperationCancelledException))와 같은 검사를 추가할 수도 있지만 이 역시 보기 좋지 않죠.

해결책 - is not과 함께 예외 필터링

C# 6에 도입된 예외 필터is not 연산자와 함께 활용할 수 있습니다.

catch (Exception e) when (e is not OperationCanceledException)
{
    Logger.LogError(e, "There was an error while processing {Message}.", typeof(TMessage).Name);
}

훨씬 더 멋지지 않나요? 이것이 왜 유용한가요?

  • 가독성 향상: 코드가 더 명확해져 동료 개발자가 개발자의 의도를 더 쉽게 이해할 수 있습니다.
  • 유지보수 용이성 향상: 타겟 예외 처리를 사용하면 캐치 블록의 전체 구조에 영향을 주지 않고 특정 예외를 쉽게 업데이트하거나 제거할 수 있습니다.

결론

따라서 다음에 C#에서 오류 처리 작업을 할 때는 코드를 더 효율적이고 가독성 있게 만들기 위해 ‘is not’ 연산자를 사용하는 것을 잊지 마세요.


9개의 좋아요

오… 안그래도 최근에 저런 상황이 존재했었는데 catch구문을 하나 더 파서 구분했었거든요.
좋은 방법이네요~
정보 감사합니다 ㅎㅎ

2개의 좋아요
1개의 좋아요