programing

C #의 정보를 잃지 않고 예외에 메시지를 추가하려면 어떻게해야합니까?

projobs 2021. 1. 15. 07:32
반응형

C #의 정보를 잃지 않고 예외에 메시지를 추가하려면 어떻게해야합니까?


다음 코드가 있습니다.

catch(Exception ex)
{
    throw new FatalException("An error occurred while trying to load the XSLT file.", ex);
}

이것은 불행히도 예외를 삼켜 버립니다. 다음을 수행하여이 문제를 해결할 수 있습니다.

catch(Exception ex)
{
    throw;
}

그러나 이벤트 로깅에 대한 도움말을 위해 사용자 지정 메시지를 포함하고 싶습니다.

정보 손실없이이 메시지를 예외에 추가하려면 어떻게합니까? (스택 추적 / 디버그 기호 등)


사용자가 읽을 수있는 메시지 또는 오류를 추적하는 데 유용하지만 최종 사용자에게는 유용하지 않은 특정 세부 정보와 같은 정보를 원래 예외에 추가해야하는 경우 다음을 사용할 수 있습니다. 키 / 값 쌍 사전 인 예외의 데이터 속성

실행중인 보고서 또는 처리중인 파일과 같은 정보를 기록하기 위해이를 광범위하게 사용하여 작업에서 오류 발생 시점에 정확히 어떤 일이 발생했는지 확인할 수 있습니다. 사용자는 실패 원인에 대해 직접 작업하기 때문에이 세부 정보가 필요하지 않습니다.

이를 사용하여 사용자에게 의미있는 일반 텍스트 메시지를 전달할 수도 있습니다. 유일한 문제는 데이터를 추출하고 소비자에게 유용하게 만들기 위해 로깅 프레임 워크 또는 최종 사용자 인터페이스에서 몇 가지 추가 작업을 수행해야한다는 것입니다.

예를 들어 다음과 같이 할 수 있습니다.

catch (Exception ex)
{
    ex.Data.Add("UserMessage", "An error occurred while trying to load the XSLT file.");
    throw;
}

그런 다음 클라이언트 측 코드에서 UserMessage가 존재하는지 테스트하고 존재하는 경우 Exception 대신 사용자에게 표시 할 수 있습니다.

catch (Exception ex)
{
    if (ex.Data.Contains("UserMessage"))
    {
        MessageBox.Show(ex.Data["UserMessage"].ToString());
    }
    else
    {
        MessageBox.Show(ex.Message);
    }
}

그 원래 예외는 여전히 존재합니다.

예외 로깅을 수행 할 때 수신되는 예외는 메시지로 작성한 FatalException이됩니다. 원래 예외는 ex.InnerException. 모든 스택 추적 정보 등을 가져 오기 위해 null이 될 때까지 InnerException을 계속 순환 할 수 있습니다.


요컨대,하지 마십시오.

나는 당신이 약간의 반성으로 이것을 우회하는 방법을 찾을 수 있다고 확신하지만, 나는 이것에 대해 당신 에게 강력하게 경고 할 입니다. .NET의 원래 예외 디자인에 위배됩니다. 예외는 로깅에 도움이 될뿐만 아니라 응용 프로그램 실패의 원래 원인에 대한 정보를 제공합니다.

첫 번째 옵션을 사용하면 원래 예외의 스택 추적을 유지하지만 별도의 예외로 래핑하여 추가 정보를 제공 할 수 있으므로 일반적으로 선호됩니다. 내 코드에서 예외를 기록 할 때마다 로깅 함수는 InnerException 속성을 통해 반복되어 오류에 대해 가능한 모든 유용한 정보를 찾습니다.


누군가가 좋은 대답이 필요한 경우를 대비해. 핵심은 AppDomain.CurrentDomain.FirstChanceException을 사용하는 것입니다.

IDisposable로 사용자 지정 개체를 만들어 모든 정보를 넣을 수 있습니다. 예외가 발생하면 FirstChanceException 핸들러가 해당 정보를 가져와 Exception.Data를 채 웁니다.

로컬 스레드 저장소를 사용하여 스레드를 안전하게 만드십시오. 그런 다음 코드를 잡아내는 코드가 데이터를 가져 와서 기록합니다.

예:

using(MyCustomMessage.EnterToLocalStorage("Info for logging"") ) 
{ 
...code 
...exception thrown
.... FirstChanceException examines local thread storage and get's "info for logging" and puts into Exception.Data. 
} 
//Dispose is called and all messages that were put into LocalStorage are removed. 
//So if exception was not thrown before then it like nothing happened.

Google AsyncDiagnosticStack for a good example. https://github.com/StephenCleary/AsyncDiagnostics/blob/master/src/Nito.AsyncEx.AsyncDiagnostics/AsyncDiagnosticStack.cs

ReferenceURL : https://stackoverflow.com/questions/14409988/how-can-i-add-a-message-to-an-exception-without-losing-any-information-in-c

반응형