Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C#에서 스택 추적을 유지한 채 예외(InnerException)를 다시 발생시키는 방법

C#에서 throw는 키워드로, 프로그램 실행 중에 예외를 수동으로 발생시킬 때 사용됩니다. 이렇게 발생된 예외는 요구 사항에 따라 try-catch 블록을 사용하여 처리할 수 있습니다.

catch 블록 안에서 throw 키워드를 사용하면 해당 블록에서 처리한 예외를 다시 던질(re-throw) 수 있습니다. 예외를 다시 발생시키는 것은 호출자(caller)가 자신의 방식대로 예외를 처리할 수 있도록 예외를 전달하고 싶을 때 유용합니다.

throw;와 throw ex;의 차이점

여기서 중요한 점은 스택 추적(stack trace)의 보존 여부입니다.

  • throw; — 원래 예외 객체를 그대로 다시 던지기 때문에 기존의 스택 추적 정보가 그대로 유지됩니다.
  • throw ex; — 새로운 예외처럼 취급되어 현재 위치부터 스택 추적이 다시 시작되므로, 원래 예외가 발생한 지점의 정보가 손실됩니다.

따라서 스택 추적을 잃지 않고 예외를 다시 발생시키려면 반드시 throw;를 사용해야 합니다.

예제 코드

다음은 C#에서 try-catch 블록과 throw 키워드를 사용하여 예외를 호출자에게 다시 전달하는 예제입니다.

class Program{
    static void Main(string[] args){
        try{
            Method2();
        }
        catch (System.Exception ex){
            System.Console.WriteLine($"{ex.StackTrace.ToString()} {ex.Message}");
        }
        Console.ReadLine();
    }
    static void Method2(){
        try{
            Method1();
        }
        catch (System.Exception){
            throw;
        }
    }
    static void Method1(){
        try{
            throw new NullReferenceException("Null Exception error");
        }
        catch (System.Exception){
            throw;
        }
    }
}

위 코드에서 Method1()에서 발생한 NullReferenceException은 catch 블록의 throw;에 의해 그대로 다시 던져지고, Method2()의 catch 블록에서도 마찬가지로 throw;를 통해 호출자인 Main 메서드로 전달됩니다. 이 과정에서 원래 예외가 발생한 지점의 스택 추적 정보는 손실되지 않습니다.

실행 결과

at DemoApplication.Program.Method1() in C:\Users\Koushik\Desktop\Questions\ConsoleApp\Program.cs:line 49
at DemoApplication.Program.Method2() in C:\Users\Koushik\Desktop\Questions\ConsoleApp\Program.cs:line 37
at DemoApplication.Program.Main(String[] args) in C:\Users\Koushik\Desktop\Questions\ConsoleApp\Program.cs:line 24 Null Exception error

실행 결과를 보면 예외가 Method1(), Method2(), Main()을 거치며 전달되었음에도 불구하고, 최초 예외 발생 지점(Method1())의 정확한 파일 경로와 라인 번호가 모두 출력되는 것을 확인할 수 있습니다.

정리

C#에서 예외를 다시 발생시킬 때 스택 추적을 유지하려면 catch 블록에서 매개변수 없이 throw;만 사용하는 것이 올바른 방법입니다. 반면 throw ex;와 같이 작성하면 스택 추적이 재설정되어 디버깅 시 실제 오류 발생 지점을 찾기 어려워질 수 있으므로 주의해야 합니다.