다음 본문은 도서 이펙티브 C# (빌 와그너)에서 나오는 주제를 다룹니다.
예외 객체에 포함된 기존 오류 관련 정보를 훼손하지 않으면서도 저수준의 에러 내용을 응용프로그램 관점으로 재해석한 정보를 예외 객체에 포함시키고 싶을 수 있다. 이 경우 사용자 지정 예외 클래스를 만들 수 있다.
예외클래스의 목적
catch문을 작성할때 예외의 런타임 타입에 따라 서로 다른 작업을 수행하는게 일반적이다.
try
{
Foo();
}
catch(MyFirstApplicationException e1)
{
FixProblem(e1);
}
catch(AnotherApplicationException e2)
{
ReportErrorAndContinue(e2);
}
catch(YetAnotherApplicationException e3)
{
ReportErrorAndShutdown(e3);
}
catch(Exception e)
{
ReportGenericError(e);
throw;
}
finally
{
CleanupResources();
}
따라서 특정 예외상황에서 특별한 처리를 하고 싶을때 예외 클래스를 만드는 것이 좋다. 다른 작업이나 복구 메커니즘으로 이어질 가능성이 있다면, 그 내용을 예외클래스에 담는 것이 도움이 된다.
2. 예외 클래스 만들기
1. 개별 예외 클래스의 고유한 책임을 명확하게 규정해야한다.
2. 모든 예외 클래스의 이름은 Exception으로 끝나야 한다.
3. System.Exception클래스나 혹은 더 적절한 클래스를 상속해서 구현해야한다.
새로운 예외클래스를 작성할 때는 반드시 4개의 생성자를 작성해야 한다.
// 기본 생성자
public Exception();
// 에러 메시지를 포함하는 생성자
public Exception(string);
// 에러 메시지와 내부 예외를 포함하는 생성자
public Exception(string, Exception);
// 입력 스트림을 이용하는 생성자
protected Exception(SerializationInfo, StreamingContext);
마지막 생성자는 예외 클래스가 serializae 가능해야 함을 의미하는 것이기도 하다.
[Serializable]
public class MyAssemblyException : Exception
{
public MyAssemblyException() : base()
{
}
public MyAssemblyException(string s) : base(s)
{
}
public MyAssemblyException(string s, Exception e) : base(s, e)
{
}
protected MyAssemblyException(SerializationInfo info,
StreamingContext cxt) : base(info, cxt)
{
}
}
예외 변환
저수준의 예외에 대해서 보다 세부적인 상태 정보를 포함하는 고수준의 예외로 변경하는 작업
public double DoSomeWork()
{
try
{
//...
return ThirdPartyLibrary.ImportantRoutine();
}
catch(ThirdPartyException e)
{
var msg = $"Problem with {e.ToString()} using library";
throw new DoingSomeWorkException(msg, e);
}
}
결론
별도로 다루는 것이 적절하다고 생각되는 오류라면 독립된 예외클래스를 만들자.
'🌍 C# Study > 이펙티브 C#' 카테고리의 다른 글
[48] 강력한 예외 보증을 준수하는 것이 좋다 (0) | 2021.05.13 |
---|---|
[46] 리소스 정리를 위해 using과 try/finally를 활용하라 (2) | 2021.05.13 |
[45] 메서드가 실패했음을 알리기 위해서 예외를 이용하라 (0) | 2021.05.12 |
[44] 바인딩 된 변수는 수정하지 말라 (0) | 2021.05.12 |
[43] 쿼리 결과의 의미를 명확히 강제하고, Single()과 First()를 사용하라 (0) | 2021.05.12 |