Effective C# 에 보면 "ITEM #44. 애플리케이션에 특화된 예외 클래스를 완벽하게 작성하라." 라는 조언?! 이 있다. 아쉽게도 일하는곳에서는 배울만한 것이 아무것도 없기에 답답해 하다가 Head First C# 을 보고 Exception 처리에 대한 기본이라 생각해 정리해 본다.


 "하나의 클래스가 예외를 발생시키면 또 다른 클래스는 예외를 잡아냅니다."

 예외를 발생시킨다는 사실 뒤에 숨어있는 핵심 요지는 무엇이 잘못될 것인가 하는 것이며, 따라서 이에 대한 비상 계획을 수립할수 있다. 일반적으로는 예외를 발생 시키고 동시에 그것을 잡아내는 메소드는 그리 흔하지 않다. 하나의 메소드에서 예외를 발생시키면 다른 객체의 또 다른 메소드에서 잡아내는 경우가 대부분이다.



즉, 위와같이 Hive 객체가 BeeProfile 객체를 생성 또는 BeeProfile의 메소드를 호출 하였을 때,  BeeProfile 에서 예외가 발생하면 BeeProfile 객체 내부에서 try-catch 로 자신의 예외를 잡아서 오로지 true, false 로 결과만 리턴해 주는게 아니다. BeeProfile 객체는 예외를 발생시켜 구체적인 예외를 던지고, 피 호출자가 해당 예외를 잡아, 각각의 예외에 맞는 처리를 해주는 것이다.



 "예외 클래스 작성"

.NET 에서 발생하는 예외 클래스들의 최상위 클래스는 Exception 클래스 이다. 따라서 사용자가 정의할 예외는 Exception 클래스를 상속 받아 자신만의 예외 클래스를 작성하면 된다.



Excpetion 클래스를 상속받아 기본 생성자만을 사용할 수 있지만, 생성자에 메시지를 인자로 갖는 생성자를 사용하여 예외가 발생한 이유를 직접적으로 알릴 수 있도록 한다.


핵심 정리!!

1. 런타임 시, 실패하는 뭔가가 발생하면 어떤 문장이라도 예외를 발생 시킬 수 있다.

2. 다양한 종류의 예외가 있는데, 각각은 Exception에서 상속받은 객체를 갖고 있다. Exception이 아닌 특정한 예외를 잡아낸다.
:  다형성에 의해 Exception 으로 모든 예외를 다 받을 수 는 있지만 발생한 각각의 예외에 따른 정확한 처리를 위해 Exception 이 아닌 해당 예외 객체로 예외를 잡고 처리해야 한다.

3. 대부분은 ArgumentException 같은 .NET 이 제공하는 예외만 발생시켜도 된다. 다른 여러 종류의 예외를 사용하는 이유는 사용자에게 각각에 대한 정보를 제공해 주기 위해서 이다. "알려지지 않은 에러가 발생했습니다." 와 같은 텍스트를 보여주는 창을 띄우는 것 보다는 "선택한 폴더가 비어있습니다. 파일이 있는 다른 폴더를 선택하세요" 를 보여주는 것이 훨씬 도움이 될 것이다.



"역사상 최악의 catch 블록 : 주석"



위 예제에서 인자로 전달받은 divisor 가 0 이면 0 으로 나누는 식이 되기 때문에 DivideByZeroException 이 발생한다. 그렇다면 이 코드가 왜 최악의 catch 블록인걸까??

묻어두는 예외

위 코드에서 0 으로 나누는 경우가 발생할 경우 try-catch로 일단 예외를 잡았기 때문에 프로그램이 비정상 종료 되지는 않는다. 하지만 0으로 나누는 경우 발생하는 예외로 인한 적극적인 처리, 알림이 없기 때문에 런타임에는 도대체 quotient가 비정상적인 값이 나오는지 알 수가 없다. 비정상 적인 값이 나온다고 일일이 디버깅 할 수도 없는 노릇이고. 더 복잡한 코드에서 이런 경우가 발생하면 한참을 디버깅 할 것이다. 퇴근은 못하겠지.. 하지만 상사는 퇴근하겠지... 
협업으로 개발하는 코드를 보면 저런 코드가 상당히 많다. 내가 뭐라할 위치가 되지 않아 가만히 두고 있는데... 상당히 안타깝다...



"일시적인 해결책도 당분간은 쓸모가 있습니다."

 예외가 발생하였을 경우, 상황에 따라 개발자가 해결책을 유도하기 보다 사용자에게 오류의 원인을 알리고, 올바른 해결책의 정보를 제공해줘야 할 때가 있다. 또한 개발자도 예외 발생 시 메시지를 발생하게 하여 해당 메시지로 예외의 원인을 파악하게 할 수 있다. 예외를 처리하는 것만큼 좋은 것은 아니지만 아무것도 하지 않는 것보다는 낫다.



"프로그램이 산산히 부서지는 것은 절대 좋지 않지만, 프로그램이 왜 충돌하고 사용자의 데이터를 가지고 무슨 일을 하는지 알지 못하는 것이 더 나쁩니다. 언제나 예상할 수 있는 에러를 처리했는지 확인하고, 처리하지 못하는 것을 기록해야 하는 이유가 바로 여기 있습니다."



예외 처리를 위한 몇 가지 간단한 팁!!

1. 에러를 우아한 방식으로 처리하는 코드를 작성하세요.

2. 사용자에게 도움이 되는 에러 메시지를 보여주세요.

3. 가급적이면 내장 .NET 예외를 던지세요. 자신만의 정보를 제공해야 할 때문 사용자 정의 예외를 발생시키세요.

4.  try블록에서는 프로그램을 중단할 것 같은 코드를 작성하세요.

5. 불필요한 파일 시스템 에러는 피하세요. 스트림을 사용할 때는 항상 using 블록을 사용하세요.




cf) Head First C#
Posted by six605
,