2014-06-19 1 views
1

도서관에서 작업 중이고 라이브러리에서 발생하는 모든 예외에 문맥 정보를 추가하고 싶습니다. 에는 라이브러리와 관련이없는 예외가 포함되어 있습니다 (예 : System.NullReferenceException. (아마도이 ​​추가 정보는 개발자가 코드 및/또는 데이터 문제를 디버그하는 데 도움이됩니다.) EDIT : 내 라이브러리는 중첩 될 수있는 큰 데이터 구조를 처리 중입니다. 그래서 예외가 발생했을 때 처리되는 필드의 전체 경로를 추가 정보로 포함하려고합니다. MyClass.Field1.SomeArray[10].SomeOtherField.ThisFails. (이 경우에는 예외로 추가 할 수있는 매우 유용한 정보라고 생각합니다.)도서관 예외에 추가 정보를 포함하는 방법

해결 방법 1. 포장에 예외 상황 정보를 추가하는 것이 좋습니다. 하지만 큰 단점이 있다고 생각합니다. 예외 유형을 변경해야합니다. 예를 들어, OutOfMemoryException은 라이브러리 특정 예외로 래핑되고 응용 프로그램이이 특정 예외 을 처리하는 것이 훨씬 더 어려울 것입니다 (개발자는 InnerException 속성의 유형을 확인해야합니다). 그래서 예외를 래핑하지 않으려합니다. 랩핑에 대한 추가 고려 사항은 내 라이브러리가 사용자가 구현 한 일부 객체와 함께 작동하여 특정 예외를 throw 할 수 있으며 이러한 예외의 유형을 수정하고 싶지 않다는 것입니다.

해결 방법 2. Exception.Data 사전을 사용하여 예외에이 추가 정보를 포함하십시오. 이 솔루션의 단점은 추가 정보가 Exception.ToString()의 기본 구현 결과에 포함되지 않는다는 것입니다. (Exception.ToString()의 결과에 추가 정보를 포함 시키므로 log.Write(ex.ToString());과 같은 예외를 기록하는 개발자가 쉽게 볼 수 있으므로이 방법으로 dvelopers는 다른 형식 지정 방법을 호출하는 방법을 배우지 못합니다. 내 라이브러리에서)

편집 :. 솔루션 3. 나는이 readolnly 때문에) (반사를 사용하여 exception.Message 필드의 끝에서 내 정보를 추가 생각했다. 왜 이것을 피해야하는지에 대한 충분한 이유가 있습니까?

설명 된 단점을 피할 수있는이 문제에 대한 가능한 다른 해결책이 있습니까? 다른 더 나은 솔루션이 없다면 가장 일반적인 구현은 무엇입니까?

편집 : 나는, 그것을 명확하게하기 위해이 도서관이기 때문에, 나는 그들이 읽을 사용자가 사용할 로깅 예외의 종류 및 얼마나 많은 라이브러리 설명서의 많은 통제권을 가지고 있지 않고, 원하는 . ex.ToString()의 결과에 최대한 많은 정보를 포함시켜 무의미한 지원 요청을 피하고 싶습니다.

또한 성능은이 라이브러리에 중요합니다 (마케팅 용일 수도 있지만 더 중요합니다). 따라서 잘 작동하는 시나리오에 대해서는 추가 처리가 필요하지 않습니다. 가능한 경우 데이터가 잘못된 경우 if (data.Field == null) throw new ArgumenNullException("someField");과 같은 몇 가지 추가 검사를 피하기 위해 나중에 편리한 위치에서 catch하고 사용할 수있는 NullReferenceException 코드가 조금씩 실패합니다. 일부 메소드는 데이터를 추가합니다.당신이 Exception.Data에서 물건 기본 ToString()을 결합 할 수있는 유형 Exception에 확장 방법으로, 새로운 방법과 같은 ToLogString()을 추가하는 열려있는 경우

+0

종속성 주입 예외 처리기를 사용하고 모든 클래스의 예외가 유입됩니다. 핸들러는 예외를 forgivable, unforgivable, tolerated 등으로 분류하고 모든 로깅을 수행합니다. –

+0

@GayotFow는 구현에 대해 더 자세히 설명해 줄 수 있습니까 (이 질문에 대한 대답 일 수도 있습니다). –

+0

의존성 주입을 사용하고 있습니까? 그게 당신의 패턴이라면 나는 갈 수 있습니다. –

답변

2

.

0

다음과 같은 것이 있습니까? 당신이 당신의 새로운 내부 이전 예외의 정보를 포함하는 것을 이렇게함으로써

namespace YourLibrary 
{ 
    class Example 
    { 
     static void Main() 
     { 
      int [] v = null; 
      try 
      { 
       v[1] = 10; 
      } 
      catch(Exception e) 
      { 
       throw new MyException(e); 
      } 
     } 
    } 

    public class MyException : Exception 
    {   
     public MyException(Exception e):base(e.GetType().ToString() + e.Message) 
     {    
     } 
    } 
} 

... 당신은 e.GetType를 삽입 할 수 있습니다(). ToString()를 어딘가에 e.Message 내부도 당신이 원한다면 ... 속성 메시지는 읽기 전용이기 때문에하지만 당신은 내가봤을 때이 기지 내부에 원하는 형식 전화

편집

나는 C# 및 예외 그래서 모두 새로운 해요 ...에 대한 코드를 통과하셔야합니다 질문 나는 여기에 몇 가지 시도를 시작하고 그것이 예외 일 때 당신이 얻을 콘솔 메시지처럼 보인다. rown은 내부에 무엇입니까 메시지 ...이 속성은 생성자에서 문자열을 전달할 때 설정되며 읽기 전용으로 변경할 수 없으므로 문제가 해결 될 것이라고 생각합니다.

1

넓은 케이스 세트를 정의하고 라이브러리가 던질 수있는 세부적인 예외를 어느 정도 정의하는 것이 좋습니다. 이는 사용자 부분에 대한 오용으로 인해 예외가 발생하더라도 라이브러리가 (사용자가 제어 할 수있는 범위 내에서) 정의 된 기대에 부합하지 못하게하는 예외입니다.

예 : 누락 값 누락 - 배치하는 규칙을 따르도록 라이브러리 사용자를 항상 강요 할 수 없기 때문에 자연스러운 것을 던지십시오. throw new ArgumentNullException("Some message") 또는 new MyLibraryArgumentNullException()을 던져주십시오.

경우에 따라 throw new MyLibraryCantDoThisBecauseOfThatException().과 같은 맞춤 예외 집합을 소개 할 수 있습니다. 내 의미를 갖습니다.

출력을 생성 할 수 있도록 필요한 모든 검사를 추가하면 다른 것을 래핑하지 마십시오. 당신의 라이브러리를 확인하고 제어하여 메뚜기 내 작업을 완료하지 못하도록하는 모든 예외를 발생한다 경로 아래 지침에 따라

public SomeObject SomeProcess(AnotherObject anotherObject){ 
    if(anotherObject==null) throw ArgumentNullException(); 
    if(anotherObject.MustBePositive<=0) throw ArgumentException("x must be positive"); 
    if(_someDepenedencyMyLibaryCreates.NotThere) throw new MyLibraryMissingDepencyException() 

    NowIHaveEnoughInfoToDoMyJobWithNoTry(); 
} 

. 만약 당신이 기억 이슈 등으로 빠지면 나는 당신이 당신의 협상에 따라 살았 기 때문에 자연스럽게 그 도서관에서 추락하게 할 것입니다. 사용자는 특별한 디코더 링없이 쉽게 추적 할 수있는 예외적 인 정보를 충분히 확보해야합니다.

색인 범위와 같은 코드에 버그가 남습니다. 모든 것을 래핑하고 SomethingBadHappened 예외를 던지면 코드가 훨씬 더 어려워 지므로 자연스럽게 떠 다니게 할 것입니다.

이제 시스템의 중요한 내부를 나타내는 비즈니스 유형 코드의 데이터베이스 예외 또는 예외와 같은주의 사항이 있습니다. 이러한 상황에서 특정 비즈니스 클래스 예외 또는 데이터베이스 예외를 감싸거나 검사하고, 원본을 로깅하고, guid 또는 기록한 예외에 대한 일부 참조를 사용하여 예외를 반환해야 할 수 있습니다.

또 다른 엣지의 경우는 특정 http 응답 코드에 의존하는 웹 서비스 라이브러리가 있습니다. 그 때문에 나는 Exception Shielding을 들여다 보았습니다.

+0

나는 이것이 아주 좋은 대답이라고 생각한다. 나는 일반적으로 모든 입력 데이터의 유효성을 확인하고 적절한 예외를 throw하는 것이 좋습니다. 나머지 코드는 시스템 문제이거나 코드의 오류이므로 추가 정보가 필요하지 않습니다. 나는 또한 나의 디자인에서 이것을 고려했다. 어쨌든, 가능한 경우 입력 데이터의 명시적인 유효성 검사를 피하고 싶은 이유를 설명하기 위해 질문을 업데이트했습니다. –

1

일부의 생각은 : 라이브러리 예외에 추가 정보를 추가

  1. 경우, 당신은 그렇게 유일한 라이브러리 될 것입니다. 모든 사용자는 추가 정보를 얻는 방법을 배워야합니다.
  2. 대부분의 라이브러리가 이와 같은 것을하지 않는다는 사실은 여러분에게 힌트가 될 것입니다. 필요하지 않거나 유용하지 않거나 이미 완료했을 것입니다. .NET은 12 년 전부터 존재 해 왔습니다. 이 휠이 왜 아직 발명되지 않았는지 스스로에게 물어볼 필요가 있습니다.
  3. 특별한 경우를 제외하고는 특별한 경우를 제외하고는 특별한 기능을 실제로 사용해야합니다. 특수 기능은 실제로 라이브러리의 요구 사항이어야하며 수락 기준 및 수락 테스트가 완료되어야합니다.

사실 실제로 특정 예외를 잡거나 예외에 추가 정보를 제공 할 필요가 거의 없습니다. 이것은 특히 추가 정보가 로깅에만 사용되는 경우에 해당됩니다.

P. 로깅에 대한 흥미로운 아이디어는 Semantic Logging Application Block을 참조하십시오. 비록 당신이 사용하지 않더라도, 그것 아이디어는 재미있다.

+0

예외 처리를위한 일관되고 예측 가능한 전략을 가지고 있어도 괜찮습니까? 나는 새로운 정보를 추가하지 않는다는 것에 동의하지만, 내가 작업 한 대부분의 대규모 응용 프로그램은 로깅 및 예외 처리에 대한 정책을 가지고 있으므로 관리하기 어려워지지 않습니다. –

+2

대부분의 경우 균일하고 예측 가능한 전략은 "예외를 처리하지 않음"이어야합니다. 그런 다음 응용 프로그램이 해당 요구 사항을 충족시키지 못하게 될 때이를 확인합니다. 그런 다음 가능한 한 늦게 요구 사항을 충족시키기에 충분한 예외 처리를 추가하기 시작합니다. 가정 한 것보다 예외 처리가 훨씬 덜 필요하다는 것을 알게 될 것입니다. –

+0

매우 통찰력있는, 감사합니다 –

관련 문제