본문 바로가기
Programming

예외처리 꼭 필요한가?

by BITINITIALIZE 2008. 5. 8.
728x90

제목에 대한 결론부터 말하자면 필요하다.


최근 며칠 사이 예전에 같이 일했던 프로그래머로부터 테스트와 분석을 요청받은 2개의 프로그램이 있었다.
회사 제품이라 어떤 프로그램인지는 말할 수 없지만 이 글을 쓰게 하는 동기가 되었다.
2개의 프로그램 모두 잘못된 예외처리로 인해서 사용에 큰 불편이 있었다.




01. 잘못된 예외처리는 불편함을 초래한다



2년전 쯤? 로보헬프(RoboHelp)라는 어플리케이션을 사용해본 적이 있었다.
이 프로그램은 윈도우의 도움말(*.chm)을 쉽게 만들 수 있도록 도와주는 어플리케이션이다.
원 제작사의 이름은 기억나진 않지만 Adobe가 인수해서 현재도 팔고 있는 제품이다.


사용자 삽입 이미지

























Adobe RoboHelp의 최신버전은 7인 것으로 알고 있는데 불과 6까지만 해도 존재했던 문제이다.


많은 어플리케이션에서 마법사 모드(Wizard)라는 걸 제공한다.
로보헬프 역시 도움말을 만드는 단계로 마법사 모드로 프로젝트를 시작할 수 있었고 여러가지 다양한 종류의 템플릿을 사용자가 선택하는 방식으로 도움말 프로젝트를 생성할 수 있다.


문제는 특정 템플릿을 선택하고 다음(NEXT)만 누르면 디폴트 설정 값으로 프로젝트가 생성되어야 함에도 불구하고 완료단계에서 비어있거나 잘못된 인자로 인해서 미칠듯한 예외처리 메시지를 보여주고 있었으며 예외처리로 인한 수많은 클릭 후에도 프로그램을 재시작하기 전까지는 어떠한 행동도 취할 수가 없었다.


마찬가지로 나에게 테스트를 요청했던 프로그래머도 비슷한 실수를 저지르고 있었다.
자동 충돌 보고서를 생성하는 것도 아닌데 수많은 예외사항들에 대한 정보를 사용자에게 보여주며 또한 예외정보도 쉽게 마우스로 드래그해서 복사할 수 있는 것도 아닌데 4~5번 정도의 무의미한 확인 버튼을 클릭한 후에야 프로그램을 종료할 수 있었다.


 


02. 예외처리 언제 사용되어야 하는가?




프로그래밍 스킬이 늘다보면 누구나 한번쯤은 보다 강력한 프로그램을 만들고 싶어하고 예외처리에 대해서 공부하게 된다. 그러나 이 예외처리를 잘못 사용하는 경우가 꽤 많다.



단지 프로그램을 죽지않게 하려고 예외처리를 남발하는 것은 옳지 않다.



사용자에게 아무런 경고도 주지 못하고 뻗어버리는 프로그램이 과연 나쁜가? 물론 나쁘다.
그동안 작업했던 내용을 날릴 수도 있고 오랜 시간이 걸리거나 중요한 작업을 하는데 프로그램이 죽으면 사용자는 프로그램을 신뢰할 수 없게 될런지도 모른다.



단지 프로그램이 죽지 않게하기 위해서 예외처리를 하는 경우 그 다음 동작은 당연히 정상적으로
동작되어야 한다. 현실은 프로그램을 재시작해야만 정상적으로 동작하는데 죽지않게 하려고 예외처리를 했으면 사용자에게 왜 간단한 정보만 보여주자. 예외 발생을 알리기 위해 수많은 확인 버튼을 누르게 하는것은 많은 불편을 초래한다.



예외에 대한 온갖 시시콜콜한 모든 사항들 콜 스택 정보, CPU 레지스터 정보, 에러가 발생한 소스의 라인, 운영체제의 정보나 각종 DLL 버전정보를 모두 보여줄 필요는 없다.
물론 발생한 예외에 대한 정보를 사용자가 인지하고 리포트할 수 있도록 보여주는 것이 스펙이라면 쉽게 복사할 수 있도록 에디트 박스 같은 곳에 넣어야 하고 예외를 보고하기 위해 캡쳐를 하게 하면 안된다.



예외처리가 사용되어야 할 시점에 대해서는 2가지의 의견이 대부분이다.



  첫번째는 모든 코드에 대해서 예외처리를 하자는 것이고
  두번째는 코드나 논리가 깨질 수 있는 약한 부분에만 한정적으로 예외처리를 해야 한다는 의견이다.



이것은 신념에 대한 문제이기도 하고 온라인상에서 폭탄메일이나 모욕을 동반한 플레임으로도 이어지는 민감한 문제이기도 하다. 양측 의견 모두 일리가 있고 뭐가 옳고 틀린지는 상황에 따라서 그리고 개발자의 역량에 따라서 달라지는 문제이기도 하기 때문에 이것이 옳다~!라고 말할 수는 없다.



본인의 경우 두번째 스타일을 고수한다.
어떠한 코드라도 논리적으로 빈약한 부분이나 깨질 수 있는 코드가 존재한다.
특히 메모리 할당, 포인터 사용, 파일 입출력 등에 대해서 어느 누구도 리턴값이 성공이라고 보장할 수가 없다.



03. 초보자를 위한 간단한 예외처리의 예



CInternetSession session("WebpageReader");
CHttpConnection* pServer = NULL;
...
...

try
{
    ...
    pServer = session.GetHttpConnection(strServerName, nConnetionPort);
    ...
    while(pFile->ReadString(strHTMLReadData))
    ...
    ...
}
catch(CInternetException* pEx)
{
    ...
    if (pServer != NULL)
    {
       delete pServer;
       pServer = NULL;
    }
    session.Close();
    ...
}


이해를 돕기 위해 특정한 웹페이지를 읽어주는 프로그램을 만든다고 했을 때 간단한 예외처리를 한 경우다.
try ~ catch 가 없을 때 예외가 발생한다면 메모리 릭이 발생할 수 있는 가능성이 짙다.
그러나 이렇게 예외처리를 통해서 pServer에 메모리가 할당이 되면 반드시 삭제가 될 것이고
세션은 반드시 닫히게 되어 있기 때문에 보다 견고한 코드를 작성할 수 있다.


정리하자면, 예외를 발생할만한 동작을 하는 코드를 try 블록에, 예외가 발생되면 catch 블록에 넣는 것이다.
C++강의를 하자는 것은 아니기 때문에 간단한 예만 보였을 뿐 다른 모든 프로젝트에 응용이 가능하고 보다 강력하고 자세한 코드를 작성하려면 MSDN을 보면서 연구 꽤나 해야 한다.


예전에 이XXX 에서 근무할 때는 회사의 주 제품이 델파이와 VC++ 모두를 사용하고 있는데 핵심 제품은 모든 부분이 델파이7으로 작성된 프로그램이었다. 속도를 높이기 위해 중간 중간 인라인 어셈으로 작성된 부분도 있었지만 규모가 상당한 프로그램이었고 개발팀에서는 프로그램의 질을 높이기 위해 자동으로 충돌을 수집하기 위해서 유레카로그(EurekaLog)라는 컴포넌트를 구매해서 사용했다.

유레카로그 이 녀석은 예외처리에 대한 꽤 좋은 컴포넌트로 치명적인 에러나 예외가 발생하면
각 유닛과 메소드에 대한 정보, 콜 스택과 레지스터, 소스 라인, 운영체제 정보, 캡쳐까지 모조리 취합하여 하나의 보고서를 생성한 다음에 사용자의 클릭 한번으로 개발팀이 지정한 곳으로 Email까지 전송해준다.

안타깝게도 VC++에서 EurekaLog처럼 딱 손에 맞는 컴포넌트를 찾지 못했다.
기능이 뭔가 부족하거나 실제 프로젝트 적용하기에는 매우 복잡하거나 해서...지금은 프리와 상용 모두에 적용이 가능한 충돌 수집기법에 대해서 연구중이다.

오늘의 결론.

1. 코드가 깨질 수 있는 부분에 대해서 꼭 예외처리를 하자.
1. 예외사항에 대한 정보는 되도록 간결하게 사용자에게 보여주자.
2. 사용자가 리포트하기 쉽도록 자동으로 충돌보고서를 생성하고 수집하자.
3. 때로는 그냥 죽는것도 괜찮다.
4. 예외처리에 대한 별도의 컴포넌트를 부착하거나 외부 클래스의 사용도 괜찮다.
5. 아놔 먹고 살기 힘들다.



[보너스 스샷 ]
최근에 만들고 있는 일명 '조사하면 다나와' 프로젝트의 개발 버전 스샷

사용자 삽입 이미지

728x90

댓글