글 작성자: 써니루루

Error Handling Guide - Rethrow to preserve stack details



훈스닷넷(Hoons.kr)에 다음과 같이 try - catch 구문에서 throw의 사용에 대해 질문이 올라왔습니다.

 

글쓴이: 주니
제목: try...catch 에 대해서...
2009-04-02 오후 8:57:59
주소 : http://www.hoons.kr/Board.aspx?Name=QAASPNET&Mode=2&BoardIdx=21940

aspx 페이지에서 biz단 함수를 호출하게 되고 biz단 함수에서는 dbbiz를 호출하게 됩니다.
 
그런 try catch 문을 세 곳 다 걸었습니다.
 
catch문에 에러로그를 남기기위해 에러로그 함수를 불렀다가 throw로 타는 형태로 되어있습니다.
 
제가 개념이 약해서 그런데..제일 마지막 dbbiz 단에서 에러가 나서 catch문을 타면 dbbiz catch만 타게 되는건가요?
 
아니면 다시 돌아오면서 catch문을 다 타게 되는건가요??
 
에러로그 함수 호출은 한곳만 불러야되는데...aspx에 넣어야할지..다 넣어야할지가 ㅡ.ㅡ;;;;;




이에 대한 저의 답변

에러 로그 함수는 aspx에서만 하시고요. Exception에 대해서 e로 받으셨다면 e.StackTrace 값을 찍어보시면 어디에서 부터 catch 되어 넘어왔는지 알 수 있습니다.

단, biz와 dbbiz에서 throw는 e를 던지는
throw e 구문은 StackTrace를 타지 않고, 해당 부분부터 다시 StackTrace를 시작하므로 나중에 어디서 에러가 났는지 찾기 힘들어집니다.
throw e; 형식보다 throw 형식으로만 던지도록 작성하세요.

참고하실 주소 : http://msdn.microsoft.com/ko-kr/library/ms182363.aspx



자세한 내용은 다음과 같이 MSDN의 설명이 있습니다.







참고하실 주소 : http://msdn.microsoft.com/ko-kr/library/ms182363.aspx

TypeName

RethrowToPreserveStackDetails

CheckId

CA2200

Category

Microsoft.Usage

Breaking Change

Non Breaking (주요 변경 아님)

 

 

원인(Cause)

예외가 다시 throw되며 예외가 throw 문에 명시적으로 지정되어 있습니다.
An exception is re-thrown and the exception is explicitly specified in the throw statement.

 

규칙 설명 (Rule Description)

예외가 throw된 경우 예외가 제공하는 정보에는 스택 추적 정보가 포함되어 있습니다. 스택 추적은 예외를 throw한 메서드로 시작되어 예외를 catch한 메서드로 끝나는 메서드 호출 계층 구조 목록입니다. throw 문에 예외를 지정하여 예외가 다시 throw되면 현재 메서드에서 스택 추적이 다시 시작되고 예외를 throw한 원래 메서드와 현재 메서드 간의 메서드 호출 목록이 손실됩니다. 원래의 스택 추적 정보를 예외와 함께 유지하려면 예외를 지정하지 않고 throw 문을 사용합니다.
Once an exception is thrown, part of the information it carries is the stack trace. The stack trace is a list of the method call hierarchy that starts with the method that throws the exception and ends with the method that catches the exception. If an exception is re-thrown by specifying the exception in the throw statement, the stack trace is restarted at the current method and the list of method calls between the original method that threw the exception and the current method is lost. To keep the original stack trace information with the exception, use the throw statement without specifying the exception.

 

위반 문제를 해결하는 방법 (How to Fix Violations)

이 규칙 위반 문제를 해결하려면 예외를 명시적으로 지정하지 않고 예외를 다시 throw합니다.
To fix a violation of this rule, re-throw the exception without specifying the exception explicitly.

 

예제(Example)

다음 예제에서는 이 규칙을 위반하는 CatchAndRethrowExplicitly 메서드와 규칙을 충족하는 CatchAndRethrowImplicitly 메서드를 보여 줍니다.
The following example shows a method, CatchAndRethrowExplicitly, which violates the rule and a method, CatchAndRethrowImplicitly, which satisfies the rule.

using System;

 

namespace UsageLibrary

{

class TestsRethrow

{

static void Main()

{

TestsRethrow testRethrow = new TestsRethrow();

testRethrow.CatchException();

}

 

void CatchException()

{

try

{

CatchAndRethrowExplicitly();

}

catch(ArithmeticException e)

{

Console.WriteLine("Explicitly specified:{0}{1}",

Environment.NewLine, e.StackTrace);

}

 

try

{

CatchAndRethrowImplicitly();

}

catch(ArithmeticException e)

{

Console.WriteLine("{0}Implicitly specified:{0}{1}",

Environment.NewLine, e.StackTrace);

}

}

 

void CatchAndRethrowExplicitly()

{

try

{

ThrowException();

}

catch(ArithmeticException e)

{

// Violates the rule.

throw e;

}

}

 

void CatchAndRethrowImplicitly()

{

try

{

ThrowException();

}

catch(ArithmeticException e)

{

// Satisfies the rule.

throw;

}

}

 

void ThrowException()

{

throw new ArithmeticException("illegal expression");

}

}

}


너무 무차별적으로 해설이 없이 소스만 있지만 -_ -;; 이해해주시길..
천천히 분석해볼만 할거에요;;