2008-08-22 13 views
9

나는 그 사용자에게 전자 메일을 보내는 유틸리티에 사용자 ID를 제공하는 코드를 가지고 있습니다.특정 문제 또는 일반적인 예외에 대한 예외를 작성합니까?

emailUtil.sendEmail(userId, "foo"); 

public void sendEmail(String userId, String message) throws MailException { 
    /* ... logic that could throw a MailException */ 
} 

MailException는 여러 가지 이유로 발생 될 수있는 전자 메일 주소 문제, 메일 템플릿 문제 등

내 질문은 이것이다 : 당신의 모든 사람을위한 새로운 예외 형식을 만들려면 어떻게해야합니까 이러한 예외를 처리 한 다음 개별적으로 처리하거나 하나의 MailException을 만든 다음 실제 발생 된 내용을 기반으로 다른 작업을 수행 할 수있는 예외 (컴퓨터가 읽을 수있는 설명 텍스트가 아닌)에 저장합니다.

편집 : 설명 : 로그에 대한 예외는 아니며, 코드에 대한 반응과 관련이 있습니다. 메일 예제를 계속 사용하려면 이메일 주소가 없기 때문에 메일을 보낼 때 유효한 이메일 주소가 없거나 실패 할 수 있다고 가정 해 봅시다.

내 코드는 (주로 클라이언트로 반환되는 메시지는 변경하지만 실제 논리는 물론) 이러한 각 문제마다 다르게 대응할 수 있습니다.

이러한 문제 각각에 대해 예외 구현을 사용하는 것이 가장 좋을지, 아니면 내부적으로 어떤 종류의 예외가 있었는지 (열거 형이라고도 함) 코드에서 어떤 문제가 있는지 구분할 수있게하는 것이 가장 좋은 방법일까요?

답변

8

일반적으로 일반적 예외로 시작하여 필요에 따라 하위 클래스를 만듭니다. 필자는 필요하다면 일반적인 예외 (그리고 모든 하위 클래스의 예외)를 항상 잡을 수 있습니다.

Java-API의 예는 IOException이며 FileNotFoundException 또는 EOFException과 같은 하위 클래스가 있습니다. 일반적인

throws GeneralException 

충분

throws SpecificException1, SpecificException2, SpecificException3 ... 

:

당신은 모두의 장점을 얻을 이렇게하면 같은 드로 조항이 없습니다.하지만 특별한 상황에 특별한 반응을 보이기를 원한다면 언제든지 예외를 발견 할 수 있습니다.

+0

왜 downvote? 이 답변에 어떤 문제가 있습니까? – Mnementh

1

응용 프로그램의 기능에 따라 다릅니다. 당신은 응용 프로그램의 범위는 전자 메일 작고 보내는

  • 이 큰 부분입니다 이메일 전송
  • 이 특히 중요하다 고 가용성이

    • 응용 프로그램 같은 경우에는 개별 예외를 throw 할 수 있습니다 그것을
    • 이 응용 프로그램은 원격 사이트에 배포 할 것입니다 그리고 당신은 당신은 mailException에 캡슐화 된 예외의 어떤 부분 집합에서 복구 할 수 있습니다
    • 디버깅 로그를 얻을 것이다 있지만 다른

    대부분의 경우 나는 예외 텍스트를 기록하고 벌써 세분화 된 예외를 세분화하는 데 시간을 낭비하지 않는다고 말합니다.

  • 10

    내 코드에서 대부분의 예외는 사용자에게 메시지를 표시하고 로그에 기록하는 예외 처리기에서 잡힌 UI 레이어까지 퍼가기 때문입니다. 그것은 결국 예기치 않은 예외입니다.

    간혹 특정 예외가 발생하기를 원합니다 (원하는 것처럼 보임). 그러나 이것은 다소 드물고 예외를 사용하여 로직을 제어한다는 것을 나타낼 수 있습니다. 이는 비효율적이며 (느린) 종종 싫은 일이 자주 발생합니다.

    그래서 당신은 이메일 서버가 구성되지 않은 경우 특별한 논리를 실행하려는 경우, 귀하의 예제를 사용하여, 당신이 좋아하는 emailUtil 객체에 메서드를 추가 할 수 있습니다

    :

    공공 isEmailConfigured() 부울

    ... 특정 예외를 찾는 대신 먼저 호출하십시오.

    예외가 발생하면 상황이 완전히 예기치 않게 발생하고 코드가 처리 할 수 ​​없다는 것을 의미하므로 사용자에게보고하거나 로그에 기록하거나 다시 시작하는 것이 가장 좋습니다)

    예외 계층 구조에 대한 예외 코드와 예외 코드는 일반적으로 후자를 수행합니다. 완전히 새로운 클래스 대신에 새로운 에러 상수를 정의하기 만하면되는 경우, 새로운 예외를 추가하는 것이 더 쉽습니다. 그러나 프로젝트 전체에서 일관성을 유지하려고 노력하는 한별로 중요하지 않습니다.

    +0

    예외 서버 측도 로그합니까? – pjp

    +0

    @php : 네, 서버 코드라면 좋은 지적입니다. 웹이 아닌 실제 클라이언트 응용 프로그램의 경우 디버깅을 위해 클라이언트 측에 예외를 기록하는 옵션이 있습니다. –

    1

    예외를 사용하는 대신 실행하는 데 문제가있을 수있는 메서드에서 상태 개체 목록을 반환하는 경향이 있습니다. 상태 개체에는 "전자 메일 주소"와 같은 상태 개체 이름과 "잘못된 형식의 전자 메일 주소"와 같은 상태 개체 이름의 심각도 열거 형 (정보, 경고, 오류 등)이 포함되어 있습니다.

    호출 코드는 UI까지 필터링하고 자체를 처리 할 수 ​​있습니다.

    개인적으로 예외는 정상적인 코드 솔루션을 구현할 수없는 경우를위한 것입니다. 퍼포먼스 히트와 핸들링 제한은 나에게 너무 비싸다.

    상태 개체 목록을 사용하는 또 다른 이유는 여러 오류 (예 : 유효성 검사 도중)를 식별하는 것이 훨씬 쉽다는 것입니다. 결국, 한 번만 예외를 던져서 계속 진행해야합니다.

    사용자가 차단하는 대상 주소와 형식이 잘못된 URL이 포함 된 이메일을 보내는 사용자를 상상해보십시오. 조작 된 전자 메일 예외를 수정 한 다음 다시 수정하고 다시 제출하면 나쁜 언어 예외가 발생합니까? 사용자 경험 관점에서 한 번에 모든 것을 다루는 것이 더 좋은 방법입니다.

    UPDATE : 결합 답변

    @ 조나단 : 내 말은 내가 이메일을 보내,이 경우에는 작업을 평가하고, 다수의 실패 이유를 다시 보낼 수 있었다. 예를 들어, "잘못된 전자 메일 주소", "빈 메시지 제목"등.

    예외를 제외하고는 한 가지 문제를 여과하고 사용자에게 어떤 문제가 있는지 두 번째 문제. 이것은 정말 나쁜 UI 디자인입니다.

    바퀴를 개조 할 가능성이 있습니다. 그러나 대부분의 응용 프로그램은 사용자에게 최상의 정보를 제공하기 위해 전체 트랜잭션을 분석해야합니다. 컴파일러가 첫 번째 오류로 인해 멈춘 경우를 상상해보십시오. 그런 다음 오류를 수정하고 컴파일을 다시 실행하여 다른 오류로 다시 중지 시키십시오. 엉덩이에 얼마나 고통 스럽습니까. 나에게 그것은 예외를 던지는 것과 정확히 같은 문제이며, 따라서 내가 다른 메커니즘을 사용한다고 말한 이유이다.

    +1

    예외는 매우 유용하며 올바르게 사용하면 코드를 훨씬 쉽게 읽을 수 있습니다. 예외와 같은 언어 기능의 성능은 최신 가상 머신의 모든 릴리스마다 달라 지므로 if-clauses (매번 메소드의 결과를 확인하는 데 사용해야 함)에 대해 매번 측정해야합니다. 메소드의 결과를 검사하는 if-check는 코드를 복잡하게 만들고 유지 보수하기가 더 어렵게 만듭니다. 오해하지 마세요 - 때로는 상태 객체가 좋은 해결책입니다. 특히 여러 오류를 처리하면 (언급 한 것처럼) 예외보다 더 유용합니다. 그러나 결정은 잘 생각되어야합니다. – Mnementh

    2

    는 Chris.Lively

    @ 당신은 당신의 예외, 또는 심지어 "상태 코드"에 메시지를 전달할 수 있습니다 알고 있습니다. 당신은 여기서 바퀴를 재발 명하고 있습니다.

    0

    나는 예외 유형을 거의 갖지 않는 경향이 있지만 실제로는 그렇게하는 것이 아닙니다. 대신 예외를 분류하는 내 사용자 정의 예외에 열거 형을 넣습니다. 대부분의 시간에는 사용자 정의 기본 예외가 있습니다.이 기본 예외는 파생 된 예외 유형에서 재정의되거나 사용자 정의 될 수있는 몇 가지 멤버를 보유합니다.

    두 달 전 나는 예외를 국제화하는 방법에 대한 아이디어에 대해 I blogged에 대해 이야기합니다. 위에서 언급 한 아이디어 중 일부가 포함되어 있습니다.

    -1

    난 그냥

    throw new exception("WhatCausedIt") 
    

    당신이 당신의 예외를 처리 할 경우

    로 갈 것입니다, 당신은 다음 스위치 문을 사용하여 다른 대답에 반응하는 대신 "WhatCausedIt"의 코드를 전달할 수 있습니다.

    +0

    매개 변수로 전달 된 Exception의 코드 대신 예외를 서브 클래스 화하고 instanceof를 사용할 수 있습니다. – Mnementh

    0

    당신은 "(...) 만약 다른 ... 예외 코드 모드"그것이 "캐치하는 Exception 계층 모드"나에 의해 이루어집니다 경우 문제가되지 않는 예외를 찾고

    를 코드 실행을 differenciate 수 있지만 그러나 라이브러리와 같이 다른 사람들이 사용하게 될 소프트웨어를 개발한다면, 여러분의 소프트웨어가 정상적인 것보다 다른 예외를 던질 수 있다는 것을 다른 사람들에게 알려주는 자신 만의 예외 타입을 만드는 것이 유용하다고 생각합니다. 그들을 해결하십시오.

    라이브러리를 사용할 때 해당 메소드는 간단히 '예외'를 ​​실행합니다.이 예외가 발생할 수있는 요인은 무엇입니까? 내 프로그램이 어떻게 반응해야합니까? javadoc이있는 경우 원인을 설명하지만 반드시 사용해야합니다. 거기에는 javadoc가 없거나 예외가 설명되어 있지 않습니다. 너무 많은 오버 헤드 마녀는 WellChossenExceptionTypeName을 사용하여 피할 수 있습니다.

    0

    예외를 포착하는 코드가 예외를 구별해야하는지 또는 예외를 사용하여 오류 페이지로 실패하는지 여부에 따라 달라집니다. 호출 스택에서 NullReference 예외와 사용자 정의 MailException을 구별해야하는 경우 시간을 소비하고 작성하십시오. 그러나 대부분의 프로그래머는 웹 페이지에 오류를 던지기 위해 예외를 예외로 사용합니다. 이 경우 새로운 예외를 작성하는 데 많은 노력이 필요합니다.

    1

    위의 조합을 사용하면 최상의 결과를 얻을 수 있다고 생각합니다.

    문제에 따라 다른 예외를 throw 할 수 있습니다. 예 : 누락 된 전자 메일 주소 = ArgumentException.

    그러나 UI 레이어에서 예외 유형을 확인하고 필요한 경우 메시지를 표시 한 다음 사용자에게 적절한 메시지를 표시 할 수 있습니다. 개인적으로 특정 유형의 예외가 throw 된 경우 (사용자 응용 프로그램에서 UserException) 정보 메시지 만 사용자에게 표시하는 경향이 있습니다. 물론 사용자 입력을 스크럽하고 가능한 한 많이 확인하여 스택에서 예외가 발생하는지 확인해야합니다. 정규식으로 쉽게 확인할 수있는 잘못된 형식의 전자 메일에 대한 필터가 아닌 실제 시나리오에서는 예외를 생성해야합니다.

    또한 사용자 입력에서 예외를 포착하는 성능에 대해 걱정하지 않아도됩니다. 예외로 인해 발생하는 성능 문제는 루프에 던져지고 잡힐 때만 볼 수 있습니다.

    2

    반환 된 예외를 기반으로 수행 할 작업을 CODE (코드)가 결정해야하는 경우 일반적인 기본 유형을 서브 클래 싱하는 잘 명명 된 예외를 만드는 것으로 나타났습니다. 전달 된 메시지는 "인간의 눈에만"고려해야하며 너무 약해서 의사 결정을 내릴 수 없습니다. 컴파일러가 작업하게하십시오!

    당신이 체크 된 예외를 인식하지 메커니즘을 통해 상위 계층이를 통과해야하는 경우, 당신은 높은 만회 할 수 RuntimeException을 (MailDomainException)의 적절한라는 이름의 서브 클래스에 포장 할 수 있으며, 원래의 원인은 행동 에.