예외 필터링과 함께 ‘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’ 연산자를 사용하는 것을 잊지 마세요.