Usability in Practice

오류가 발생할 때

Dr. Charles Kreitzberg, Ambrose Little

코드는 MSDN 코드 갤러리에서 다운로드할 수 있습니다.
온라인으로 코드 찾아보기

목차

사용 편의성 문제
오류 메시지의 중요성
디자인 단계에서 던져야 할 중요한 질문
오류 메시지의 형식
프로그래밍 기법
일관적인 처리
잘 작성된 오류 메시지
예외 사용자 지정(Enterprise Library 사용)

kreitzberg.gif

Charles Kreitzberg

사용 편의성 문제

사용 편의성 측면에서 가장 어려운 부분은 많은 경우 오류 메시지입니다. 프로그램에서 문제가 발생하면 그 다음 무엇을 할 것인지는 전적으로 사용자에게 달려 있습니다. 무엇이 잘못되었고 어떻게 이 문제를 해결하면 되는지 사용자에게 알려 주는 오류 메시지를 프로그램에서 생성한다면 이상적일 것입니다. 그러나 많은 오류 메시지는 이러한 목적에 전혀 부합하지 않습니다.

그림 1의 오류 메시지를 살펴보겠습니다. 부팅 시퀀스 직후 필자의 PC에 표시된 오류 메시지입니다. 문제가 무엇인지 전혀 알지 못하는, 기술 문외한인 사용자가 이 메시지를 본다고 생각해 보십시오. 이 메시지는 보안에 결함이 생겼으며 손쓸 방도가 없다는 인상을 줍니다. 사실 그렇게 심각한 상황은 아니었습니다. 이후 필자는 이 오류 메시지가 비디오 편집 소프트웨어에서 발생했으며, 모든 것이 아무 문제 없이 계속 돌아간다는 사실을 알게 되었습니다. 이 메시지에는 다음과 같은 많은 디자인 결함이 포함되어 있습니다.

  1. 오류 메시지를 생성한 프로그램을 알 수 없습니다.
  2. 프로그램이 종료된 이유에 대한 설명이 없습니다.
  3. 메시지가 너무 포괄적입니다. "the security information(보안 정보)"라는 부분이 나오지만 이 정보가 대체 무엇인지 아무런 단서도 없습니다.
  4. 메시지를 보고 문제가 얼마나 심각한지, 사용자의 컴퓨터가 위험에 처했는지 여부를 알 수 없습니다.
  5. 사용자는 문제를 수정하는 방법이나 도움을 받을 수 있는 곳을 알 수 없습니다. 할 수 있는 일은 OK(확인)를 누르는 것이 전부입니다(물론 확인된 것은 아무것도 없음).

fig01.gif

그림 1 이런, Termination(종료)이라는 말이 무척 거슬립니다.

fig02.gif

그림 2 제가 없을 때 Windows가 연락하면 어떻하죠?

혼란스러운 오류 메시지로부터 자유로운 사람은 없습니다. 좋은 메시지를 만드는 방법에 대한 표준을 제안한 Microsoft조차 가끔 그림 2와 같은 엉터리 메시지를 만듭니다. 필자는 종종 이 메시지를 접합니다.

Windows Vista 사용자 환경 가이드는 오류 메시지에 대한 지침을 제공하는데, 이 지침에 따르면 좋은 오류 메시지는 다음의 세 가지 구성 요소로 이루어집니다.

  • 문제가 발생했다고 알립니다.
  • 원인을 설명합니다.
  • 사용자가 문제를 수정할 수 있도록 해결책을 제공합니다.

또한 이 지침은 좋은 오류 메시지를 표시하는 다음과 같은 방법도 제안합니다.

  • 관련성—사용자에게 직접적으로 관련된 문제를 제시합니다.
  • 조치 가능성—사용자는 메시지에 따라 조치를 취하거나 자신의 동작 방식을 바꿀 수 있어야 합니다.
  • 사용자 중심—메시지는 코드 관점에서 본 문제가 아닌, 대상 사용자의 작업 또는 목적 관점에서 문제를 설명해야 합니다.
  • 간결성—메시지는 가급적 짧아야 하지만 지나치게 짧으면 안 됩니다.
  • 명확성—메시지는 평이한 언어를 사용하여 대상 사용자가 문제와 해결책을 쉽게 이해하도록 해야 합니다.
  • 구체성—메시지는 구체적인 언어를 사용하여 문제를 설명하면서 관련된 개체의 이름과 위치, 그리고 가치를 구체적으로 제공해야 합니다.
  • 친절함—사용자를 탓하거나 위축시키면 안 됩니다.
  • 희박성—드물게 표시되어야 합니다. 자주 표시되는 오류 메시지는 잘못된 디자인을 나타내는 신호입니다.

그림 2의 오류 메시지는 이러한 조건의 대부분을 충족하지 못합니다.

오류 메시지의 중요성

최종 사용자의 능률이 중요하므로 양질의 오류 메시지는 단순히 보기 좋은 메시지가 아닙니다. 오류는 처리 작업을 중단시키고 사용자 환경을 망치고 비용 손실을 유발합니다. 사용자를 지원하기 위한 비용은 상당히 커질 수 있습니다. 사용자가 문제를 식별 및 해결하도록 하는 좋은 오류 메시지는 많은 시간과 비용을 절약하고 사용자 환경에 대한 오류의 영향을 최소화합니다. 그러나 좋은 오류 메시지를 만들기가 어려운 경우도 있습니다.

기본적으로 오류 메시지는 프로그램이 예상치 못한 상황에 직면할 때 발생합니다. 문제의 원인은 문제가 감지된 시점에서는 이미 사라졌을 수 있으며 이 경우 근본적 이유를 찾기란 불가능할 수도 있습니다. 환경을 완벽하게 제어할 수는 없지만, 유용한 메시지를 디자인하고 기술적인 문제를 사용자 중심의 조치 가능한 언어로 변환하는 데 시간을 투자하면 상황을 개선할 수는 있습니다.

디자인 단계에서 던져야 할 중요한 질문

예외를 어떻게 관리할지 구상할 때 고려해야 할 중요한 사용자 중심의 질문은 다음과 같습니다.

대상이 누구인가? 개발자, 전문 교육을 받은 사용자, 보편적인 사용자, 아니면 일반 대중?

어떤 유형의 예외를 보고할 것인가? 그리고 이러한 예외를 어떻게 표현할 것인가?

사용자가 이용 가능한 지원은 무엇인가? 예를 들어 지원 센터 및 기술 자료 지원이 사용자에게 제공되는가?

어떤 방법으로 사용자를 정상 궤도로 돌려놓을 것인가? 사용자에게 문제가 발생했다고 알리기만 하고 이를 해결하기 위한 조치 가능한 방법을 제공하지 않을 경우 이는 부정적인 사용자 환경으로 이어집니다.

예외 발생을 로깅하고 알려야 하는가? 그렇다면 사용자 또는 IT 담당자가 로그를 보고 검색하고 정렬하고 필터링하고 유지 관리하는 방법과 알림의 형식 및 내용에 대해 고려해야 합니다. 이러한 항목들은 상당히 유용합니다.

서로 다른 대상에게 개인화하여 메시지를 보여줄 것인가? 예를 들어 개발자 보기와 공개 보기가 도움이 될 것인가? 메시지 표시를 외부 정책 파일을 통해 제어할 경우 보안 취약점이 발생할 것인가?

메시지의 사용 편의성을 높일 수 있는가? 그리고 새로 만든 예외로 이 예외를 래핑해서 기본적인 기술 정보에 대한 링크를 보존할 수 있는가? 응용 프로그램 경계 너머로 기술 정보를 전달할 경우 보안 위험이 발생하지는 않는가?

이러한 질문은 프로젝트의 끝이 아니라 초반에 고려해야 합니다.

오류 메시지의 형식

오류 메시지는 최대한 이해 가능하고 정확하며 조치 가능해야 합니다. 메시지에서 다음을 전달하도록 노력하십시오.

  • 최대한 완성된 그림.
  • 사용자 관점에서 의미 있는 최대한의 컨텍스트.
  • 명확하게 제시된 사용자 조치. 사용자가 각 선택의 결과를 확실히 이해하도록 함으로써 최대한 편안한 마음으로 선택할 수 있도록 합니다.

좋은 오류 메시지를 만드는 데 도움이 되는 제안은 다음과 같습니다.

원인 식별 오류 메시지가 발생한 사이트 또는 응용 프로그램을 밝힙니다. 오류가 발생한 코드 영역을 찾는 데 도움이 될 수 있는, 보다 심층적인 정보를 제공하는 것도 좋지만 이러한 내부적인 세부 사항은 악의적 공격에 사용될 수 있으므로 사용자에게 노출할 때는 신중을 기해야 합니다. 최종 사용자에게 지나치게 기술적으로 보이지 않도록 추가적인 진단 및 조사 정보는 주 메시지와 분리해서 표시해야 합니다. 기술 지식이 없는 사용자는 기술적인 정보를 접할 필요가 없도록 요청에 따라 세부 정보를 표시하는 방법(예: 확장/축소되는 영역을 이용)을 고려해 보십시오.

평이한 언어 사용 기술적 언어를 최소한만 사용하여 설명합니다. 오류가 발생한 시점에 사용자가 무엇을 하고 있었는지 알지 못하므로 이는 어려운 부분입니다. 그러나 사용자가 수행하려고 했던 작업 및 관련 데이터와 문제의 연관성을 많이 밝혀낼수록 사용자가 오류 메시지를 이해하고 상황을 해결하기 위해 조치를 취할 수 있게 될 가능성은 더 높아집니다. 다시 말하지만, 공격에 사용되거나 개인 정보를 노출할 수 있는 정보는 노출하지 않도록 주의해야 합니다. 오류의 심각도를 알리고 가능한 경우 문제의 결과를 설명하십시오.

세부 정보 및 지침 제공 "HTML 오류 - 500 - 내부 서버 오류"와 같은 높은 수준의 예외에 대해서는 가능한 경우 더 많은 세부 정보와 구체적인 지침을 제공합니다. 사용자가 오류를 해결하기 위해 취할 수 있는 조치를 설명하되 이러한 조치에 따른 결과를 명확하게 알려 줍니다. 가능하다면 사용자가 적절한 결정을 내리는 데 도움이 되는 정보가 있는 링크를 제공합니다. 지원 부서에 연락하라는 말이 전부라면 연락처 정보가 정확하며 손쉽게 업데이트가 가능한지 확인합니다.

사용자 안내 ASP.NET의 사용자 지정 오류 페이지를 사용하는 경우 이 페이지를 사이트와 시각적으로 통합하고 관련 페이지, 또는 최소한 홈 페이지로 갈 수 있는 탐색 기능을 제공합니다. 또한 추가 정보가 있는 웹 사이트로 안내하는 경우 홈 페이지에 무성의하게 사용자를 던져두고 정보는 알아서 찾으라는 식이 아니라 관련 페이지로 직접 안내해야 합니다.

little.gif

Ambrose Little

프로그래밍 기법

필자 역시 오류 메시지가 어려워질 수 있다는 점에 동의하며 위에 나온 Charles의 모든 제안은 매우 유용합니다. 그렇다면 코드에서 실제로 이러한 제안을 구현하려면 어떻게 해야 할까요?

프로그래밍 목적상 오류 메시지는 두 가지 범주로 나누는 것이 좋습니다. 프로그램 오류는 예상치 못한 상황으로 인해 코드에서 발생하는 예외입니다. 프로그램 오류가 발생하면 대체로 프로그램을 정상적으로 종료하는 것 외에는 다른 방도가 없습니다. 사용자 입력 또는 유효성 검사 예외의 경우 사용자가 문제를 수정할 수도 있습니다. 이러한 유형의 오류에서는 잘 작성된 오류 메시지가 문제 복구의 열쇠가 되기도 합니다. 이 칼럼에서는 첫 번째 오류(프로그램 오류)에 대해 집중적으로 살펴보고, 사용자 입력 및 유효성 검사 오류는 나중을 기약하겠습니다.

일관적인 처리

아무리 잘 작성된 프로그램이라도 오류는 발생합니다. 오류를 다루기 위한 가장 좋은 방법은 프로그램 전체에서 사용 가능한 오류 메시지용 클래스를 만드는 것입니다. 모든 오류 메시지 처리를 하나의 지점으로 모으면 다음이 가능해집니다.

  1. 모든 메시지가 완성된, 그리고 일관적인 형식으로 제공되도록 합니다.
  2. 사용자 지정 예외 유형을 사용하여 각 메시지에 고유한 오류 코드를 할당함으로써 손쉽게 오류 메시지 사전을 만들고 추가 정보로 이 사전을 확장하고 필요한 경우 로컬화할 수 있습니다.
  3. 가능한 경우 사용자 지원을 제공하는 웹 사이트, 또는 최소한 사용자가 오류 메시지와 관련하여 응용 프로그램 지원 부서에 연락할 수 있는 방법을 제공하는 웹 사이트에 오류 메시지를 연결합니다.
  4. 자동으로 또는 사용자 허락하에 로그를 작성하여 서버로 보내 문제를 분석하고 소프트웨어를 개선할 수 있도록 합니다.

잘 작성된 오류 메시지

그림 34의 대화 상자는 잘 작성된 오류 메시지의 요소를 보여 줍니다. 오류 메시지가 간단하다면 Windows Vista 지침을 응용한 그림 3에 나온 것과 같은 상자를 사용할 수 있습니다. 이 오류 메시지는 사용자 수정이 가능한 오류에 가장 유용합니다. 프로그램 오류의 경우 그림 4에 나온 것과 같은 보다 광범위한 메시지가 필요할 수 있습니다.

그림 3 간단한 오류 메시지 형식

그림 4 보다 복잡한 오류를 위한 메시지

예외 처리에 대해서는 MSDN Library 기사 ".NET Framework 개발자 가이드: 예외 디자인 지침"에 잘 나와 있습니다. MSDN Library에서 "예외 처리 응용 프로그램 블록" 기사도 보시기 바랍니다. 여기에는 더 자세한 정보를 통해 만든 예외 내부에 예외를 중첩하는 래핑 기능이 있습니다. 이 기능은 예외가 발생한 컨텍스트를 포착하는 정보를 추가하는 데 사용할 수 있습니다. 이 정보를 통해 더욱 사용자 중심적인 오류 메시지를 작성할 수 있습니다.

보안 우려로 인해 기술적인 정보를 노출하고 싶지 않다면 예외를 래핑하는 대신 보다 사용자 중심적인 메시지로 바꾸면 됩니다. 마지막으로, 예외 처리 블록을 사용하여 오류를 로깅하고 전자 메일, WMI(Windows Management Instrumentation) 또는 기타 사용자 지정 메커니즘을 통해 적절한 관계자에게 알릴 수 있습니다.

ASP.NET을 위한 가벼운 오류 로깅 및 보고 기능이 필요하다면 ELMAH(오류 로깅 모듈 및 처리기)를 살펴보십시오. 이 도구는 로깅, 다양한 로그 저장 옵션, 웹 페이지와 전자 메일, RSS 알림에서 로그를 보는 기능을 제공합니다. 또한 dotNetTemplar에서 무료로 제공되는 처리기와 같은 EntLib용 ELMAH 예외 처리기를 만들 수 있습니다. 이렇게 하면 EntLib이 제공하는 인프라와 ELMAH가 제공하는 보고 서비스를 함께 얻을 수 있습니다.

Windows XP 또는 Windows Vista 환경을 위한 응용 프로그램을 구축 중이라면 Windows 오류 보고 서비스(Dr. Watson)를 고려해 보십시오. 사용자가 충돌 데이터를 제출하면 Windows 오류 보고 서비스는 이와 관련된 사용자 메시지가 있는지 확인하고 충돌 시점에 이 메시지를 제공합니다.

이 프레임워크는 예외 처리 관리를 위한 뛰어난 솔루션이지만 이것을 사용한다고 해서 사용 편의성이 보장되는 것은 아닙니다. 사용자 관점에서 상황을 보면서 사용자의 기술적 이해도를 파악하기 위해 노력하고, 명확하고 정확하며 조치 가능한 메시지를 만들어야 합니다.

이제 지금까지 설명한 개념을 보여 주는 예와 샘플 코드를 살펴보겠습니다.

예외 사용자 지정(Enterprise Library 사용)

다음은 Enterprise Library 예외 처리 블록을 사용하여 Windows Forms 응용 프로그램의 예외를 사용자 지정하는 방법을 대략적으로 설명합니다. 다른 Microsoft .NET Framework UI 기술에도 비슷한 기법을 적용할 수 있습니다.

먼저 그림 5에서와 같이 ExceptionHandling 클래스를 통해 예외 처리를 중앙화합니다. 이 클래스는 Enterprise Library 구성에 정의된 예외 정책에 직접 매핑되는 메서드가 포함된 정적 클래스입니다.

그림 5 ExceptionHandling 클래스

public static class ExceptionHandling
{
    public static Exception UiUnknown(Exception exception)
    {
        try
        {
            if (Microsoft.Practices.EnterpriseLibrary.
                ExceptionHandling.ExceptionPolicy
                  .HandleException(exception, "UiUnknown"))
                return exception;
        }
        catch (Exception ex)
        {
            return ex;
        }
        return null;
    }
}

그림 6에서와 같이 Enterprise Library Configuration 도구에서 이 정책을 구성합니다. try/catch 문에서와 비슷하게 두 유형 처리기를 지정합니다. 더 구체적인 처리기가 선택됩니다. 두 경우 모두 먼저 기본 제공되는 XML 로깅 추적 수신기가 포함된 XML 예외 포맷터를 사용하여 발생한 예외를 로깅할 수 있습니다. 일반적인 예외의 경우 보다 사용자 중심적인 메시지를 포함하는 새 예외로 원본 예외를 래핑할 수 있습니다. 예외를 교체하는 방법도 있지만 UI에 실제 예외에 대한 세부 정보가 필요한 경우를 대비하여 래핑하는 것이 더 좋습니다.

그림 6 Enterprise Library Configuration 도구

예외를 래핑하거나 교체할 때 필요한 작지만 중요한 한 가지 트릭은 예외 유형의 PostHandlingAction을 ThrowNewException으로 설정하는 것입니다. 이렇게 하면 새로운, 래핑된 예외가 발생합니다.

호출 코드에서 예외 관련 작업을 더 많이 수행하도록 하려면 NotifyRethrow를 선택하는 방법도 있습니다. 이 경우 EntLib ExceptionPolicy.HandleException에서 true를 반환하게 됩니다. 곧 보게 되겠지만 DatabaseConnectivityException의 경우 사용자 지정 예외 유형에서 사용자 중심적인 부분을 처리할 수 있으므로 앞의 정책에서 하는 일은 이를 로깅하고 다시 발생해야 함을 알리는 것이 전부입니다.

ExceptionHandling.UiUnknown을 호출하면 새로운 래핑된 예외, 원본 예외, 또는 정책이 새 예외를 발생시키지 않기로 하거나 다시 발생하도록 알리지 않기로 할 경우 아무 예외도 받지 않게 됩니다. 이 부분이 예외 처리 블록의 핵심적인 이점입니다. 즉, 응용 프로그램 코드의 외부에서 정책을 구성할 수 있습니다(방해가 되는 부분을 응용 프로그램 코드에서 떼어놓기 위한 좋은 방법임). 그런 다음 그림 7의 ErrorMessage 폼에 정의된 ErrorMessage.Show 메서드로 이를 전달합니다.

그림 7 ErrorMessage 폼

public static void Show(Exception relatedException)
{
    ErrorMessage em = new ErrorMessage();
    if (relatedException == null)
    {
        em.problemDetailsContainer.Visible = false;
    }
    else
    {
        em.problemDescription.Text = relatedException.Message;
        IUIExceptionDetail detail = 
          relatedException as IUIExceptionDetail;
        if (detail == null)
        {
            em.errorCode.Text = "500";
            em.problemDetails.Visible = false;
        }
        else
        {
            em.errorCode.Text = detail.ErrorCode.ToString();
            em.problemDetails.Text = detail.DetailMessage;
        }
        em.problemType.Text = 
          em.GetMeaningfulExceptionType(relatedException).Name;
        em._SearchText = em.errorCode.Text + " " + em.problemType.Text;
    }
    em.ShowDialog();
}

ErrorMessage 폼은 회사 브랜딩, 연락처 정보가 포함된 친절한 화면으로, 회사로 문제를 보고하는 기능과 온라인으로 해결책을 찾는 기능을 제공합니다.

예외가 주어지지 않으면 이 화면은 세부 정보 컨테이너를 숨깁니다. 자세한 정보가 없는데도 있는 듯한 오해를 불러 일으킬 필요는 없기 때문입니다. 사실 이 경우 메시지를 아예 표시하지 않을 수도 있습니다. 예외가 있는 경우에는 예외 메시지에 문제 설명을 설정합니다. 그런 다음 예외 유형이 사용자 지정 IUIExceptionDetail 인터페이스를 구현하는지 확인합니다.

이 인터페이스를 사용하면 가능한 경우 보다 의미 있는 예외 정보를 사용자에게 제공할 수 있습니다. 인터페이스의 형태는 다음과 같습니다.

public interface IUIExceptionDetail
{
    int ErrorCode { get; }
    string DetailMessage { get; }
}

이를 통해 사용자가 직접 문제를 해결하도록 돕거나 최소한 검색 및 지원을 위한 참조 역할을 하는 양질의 오류 코드를 제공하는, 의미 있는 사용자 중심의 사용자 지정 예외를 만들 수 있습니다. 이 인터페이스의 샘플 구현은 그림 8에 나온 DataConnectivityException 유형입니다.

그림 8 DataConnectivityException

public class DatabaseConnectivityException 
  : Exception, IUIExceptionDetail
{
    public DatabaseConnectivityException(Exception innerException)
     : base(Resources.Exceptions.DatabaseConnectivityException_Message, 
                innerException)
    {
        int.TryParse(
          Resources.Exceptions.DatabaseConnectivityException_Code,
          out _ErrorCode);
        _DetailMessage = 
           Resources.Exceptions
             .DatabaseConnectivityException_DetailMessage;
    }

    #region IUIExceptionDetail Members
    int _ErrorCode;
    public int ErrorCode
    {
        get { return _ErrorCode; }
    }

    string _DetailMessage;
    public string DetailMessage
    {
        get { return _DetailMessage; }
    }
    #endregion
}

여기에서 가장 흥미로운 부분은 RESX 파일을 사용하여 메시지, 오류 코드 및 세부 정보를 저장한다는 점입니다. 이 파일은 지역화가 가능하며 오류 메시지 설명서를 위한 유용한 XML 소스 역할도 합니다. RESX 형식에 XSLT를 손쉽게 적용하여 HTML 또는 기타 풍부한 텍스트 태그를 생성할 수 있습니다.

EntLib에서 제공하는 기본적인 래핑/교체 기능에 비해 이 접근 방법이 더 좋게 생각될 수도 있고, 이러한 생각이 잘못된 것도 아닙니다. 사용자 중심 메시지를 제공하기 위해 꼭 EntLib을 사용할 필요는 없지만 로깅을 위해, 그리고 최소한 응용 프로그램 외부에서 예외 처리를 사용자 지정하는 기능을 제공하기 위해 예외 처리를 정책으로 외부화하는 방법은 여전히 유용합니다.

ErrorMessage.Show 메서드를 다시 살펴보면 IUIExceptionDetail 인터페이스에 대한 확인을 볼 수 있습니다. 이 인터페이스가 발견되면 메서드는 사용자에게 보여 주기 위해 추가로 제공되는 정보를 사용합니다. 그렇지 않으면 세부 정보 상자를 숨기고 포괄적 오류 코드 500을 표시합니다(HTTP 500과 비슷함).

포괄적이고 알 수 없는 오류에 대한 결과는 그림 9에서 볼 수 있습니다. DataConnectivityException과 같은 보다 구체적인 오류가 발생하는 경우 그림 10과 같은 메시지를 받게 됩니다.

fig09.gif

그림 9 포괄적인 오류 메시지

fig10.gif

그림 10 보다 구체적인 오류 메시지

여기에는 몇 가지 주목할 점이 있습니다. 먼저, 이는 오류 메시지에 대한 Windows Vista 지침을 상당히 충실히 따른 것입니다. 창은 모달 대화 상자입니다. 대화 상자 제목은 사용자가 시스템 오류 등과 혼동하지 않도록 사용자에게 오류를 일으킨 주체를 명확히 알려 줍니다. 이 제목은 응용 프로그램의 구체적인 기능이 될 수도 있습니다. 이 오류에는 큰 아이콘이 있습니다. 이 아이콘은 응용 프로그램 로고 위에 겹쳐 표시되며 문제의 출처를 거듭 강조하는 역할과 이것이 오류임을 명확히 전달하는 역할, 두 가지 기능을 합니다. 제목 텍스트 역시 해당 응용 프로그램에 문제가 있음을 사용자에게 뚜렷이 알립니다.

제목의 바로 아래에는 예외 메시지가 표시됩니다. 이 메시지는 간결한 동시에 사용자가 이해할 수 있는 용어를 사용하여 친절한 어투로 작성되어야 합니다. 가능한 경우 해결책도 제시해야 합니다. 포괄적인 오류의 경우 해결책을 알지 못할 수 있으므로 가장 적절한 방법은 오류를 보고하거나 온라인으로 오류를 검색하도록 사용자를 안내하는 것입니다. 구체적인 문제의 경우 유력한 해결책을 알고 있다면 추가로 사용자에게 방법을 제시할 수 있습니다. 궁극적인 목표는 사용자가 스스로 문제를 해결하도록 돕는 것입니다. 포괄적인 메시지보다 구체적인 메시지가 더 나은 이유가 바로 이것입니다.

fig11.gif

그림 11 가장 중요한 단추는 "Tell Us about the Problem"

"Search for Solutions Online" 링크 단추를 누르면 "MSDN Magazine"에 오류 및 예외 유형을 더하여 검색이 수행됩니다. 검색란에 무엇을 입력해야 할지 사용자가 모를 수도 있으므로 이는 유용한 기능입니다. 사이트에 사용자 지원 섹션이 있다면 해당 사이트에서만 검색을 수행하도록 제한할 수도 있습니다. 물론 구체적인 조회 서비스(코드를 기반으로 하는)가 있는 경우에는 일반 키워드 검색 대신 이 서비스를 사용하는 것이 좋습니다.

"Tell Us About the Problem" 단추를 누르면 웹 서비스로 XML 로그가 전달됩니다. 사용자에게 컨텍스트 참고 사항 및/또는 연락처 정보를 제공하기 위한 옵션을 넣을 수도 있으며, 이 경우 서비스는 사용자가 지원을 요청할 때 참조할 수 있는 추적 정보를 반환해야 합니다.

그림 11은 다른 표시 방법을 보여 줍니다. 차이는 Tell Us About the Problem이 화면에서 가장 돋보인다는 것입니다. UI 디자인에서 고려해야 할 요소 중 하나는 시각적인 계층에 따른 사용자 유도입니다. 즉, 다른 항목에 비해 더 중요한 항목이 있거나 이 예에서처럼 사용자가 실행하도록 유도하고자 하는 명령이 있는 경우 이러한 항목이 화면에서 가장 돋보이고 명확하고 사용하기 쉬워야 합니다. 컨텍스트를 기반으로 어떤 작업이 더 중요한지 판단하고, 계층이 있는 경우 이러한 중요성을 시각적으로 전달해야 합니다.

이 부분을 구현하고 나면 Program.cs Main 메서드에 다음과 같이 응용 프로그램 수준 처리기를 추가할 수 있습니다.

Application.ThreadException += Application_ThreadException;

이 메서드는 다음과 같은 형태입니다.

static void Application_ThreadException(object sender, 
  System.Threading.ThreadExceptionEventArgs e)
{
    ErrorMessage.Show(ExceptionHandling.UiUnknown(e.Exception));
}

이 메서드는 샘플에서 Enterprise Library에 처리를 위임하는(사실 아무 예외 처리 프레임워크라도 될 수 있음) 중앙화된 예외 처리기 클래스에 있는 "UiUnknown" 정책을 통해 예상하지 못한 모든 UI 예외를 포착하여 라우팅합니다. 이 메서드는 여러분이 디자인한 보다 사용자 친화적인 ErrorMessage 폼을 통해 사용자에게 보여 줄 예외를 반환할 수 있습니다. 물론 응용 프로그램 전반에 걸쳐 보다 구체적인 예외 정책에 비슷한 접근 방법을 사용할 수 있습니다.

여기에서 볼 수 있듯이 좋은 오류 메시지를 만드는 일은 쉽지 않습니다. 그러나 시간을 투자하여 신중하게 작성한다면 사용자의 수고와 무력감을 크게 줄일 수 있습니다.

Dr. Charles Kreitzberg는 사용 편의성 컨설팅 및 사용자 환경 디자인 서비스를 제공하는 Cognetics Corporation의 CEO이며 제품의 비즈니스 목표를 지원하는 동시에 사용자의 관심을 끌고 즐거움을 주는 직관적인 인터페이스를 만드는 일에 열정을 갖고 있습니다. Charles는 뉴저지 중부에 살면서 밤에는 연주자로도 활동합니다.

Ambrose Little은 아내와 4명의 자녀들과 함께 뉴저지 중부에 살고 있습니다. 10년 이상 소프트웨어를 디자인 및 개발해왔으며 INETA 발표자, Microsoft MVP이기도 합니다. 최근 기술적 디자인에서 사람을 위한 디자인으로 활동 영역을 바꿨으며, 현재는 Infragistics에서 사용자 환경 디자이너로 일하고 있습니다.