문제

본 다음 코드는 많은 시간:

try
{
    ... // some code
}
catch (Exception ex)
{
    ... // Do something
    throw new CustomException(ex);

    // or
    // throw;

    // or
    // throw ex;
}

당신의 목적을 설명하고 다시 던지는 예외?그것은 다음과 같은 패턴/서 가장 좋은 방법은 예외 처리는?(I've read 어딘가에 그것은"호출자에게 알려"패턴?)

도움이 되었습니까?

해결책

Rethrowing 같은 예외입니다 유용하려는 경우,말,로그를 제외하지만,처리하지 않습니다.

을 던지고 새로 예외를 감싸는 잡은 예외에 대한 좋은 추상화입니다.예를 들어,라이브러리를 사용하는 타사 라이브러리는 예외가 발생하는 클라이언트 라이브러리의 안됩니다.는 경우에,당신은 당신 랩으로 예외를 입력되어 있는 라이브러리,및 던지는 대신 합니다.

다른 팁

실제로 사이의 차이

throw new CustomException(ex);

throw;

두 번째로 유지됩니다 스택 정보입니다.

그러나 때때로 당신을 제외 더 많은"친절"응용 프로그램에 도메인을 시키는 대신 DatabaseException 에 도달하 GUI,당신은 인상 사용자 지정 예외를 포함하는 원래의 예외는 아니다.

예를 들어:

try
{

}
catch (SqlException ex)
{
    switch  (ex.Number) {
        case 17:
        case 4060:
        case 18456:
           throw new InvalidDatabaseConnectionException("The database does not exists or cannot be reached using the supplied connection settings.", ex);
        case 547:
            throw new CouldNotDeleteException("There is a another object still using this object, therefore it cannot be deleted.", ex);
        default:
            throw new UnexpectedDatabaseErrorException("There was an unexpected error from the database.", ex);
    } 
}

때로는 당신이 숨기려는 구현에 대한 세부적인 사항의 방법을 개선 또는 은 추상화 수준의 문제는 더 많은 의미를 발신자 의 방법입니다.이렇게하려면,당신은 당신을 가로챌 수 있습니다 원래 예외하고 대체 사용자 지정하는 예외의 더 적합한을 설명하는 문제입니다.

예를 들어 a 방법을 로드하는 요청한 사용자의 정보에서 텍스트 파일입니다.는 방법에서는 텍스트 파일로 존재하라는 이름으로 사용자의 ID 및의 접미사".데이터".경우는 파일이 실재하지 않은,그것은 큰 의미가 없을 던져 FileNotFoundException 기 때문에 사실은 각 사용자의 정보는 텍스트 파일에 저장이 구현한 세부 내부하는 방법입니다.그래서 이 방법 대신 랩 원래 예외에는 사용자 지정 예외 설명 메시지입니다.

코드와는 달리 당신은 다음과 같이 가장 좋습은 원래 예외를 유지해야에 의해 선적으로 InnerException 산의 새로운 예외는 아니다.이는 개발자가 여전히 분석에 근본적인 문제는 경우에 필요하다.

를 만들 때 사용자 정의 예외,여기에 유용한 체크리스트:

•찾아 좋은 이름이 전달하는 왜 예외가 발생하고 있는지 확인 이름으로 끝나는 단어는"예외".

•도록 구현하는 세 가지 표준을 제외 생성자입니다.

•도록 마크의 예외 Serializable 특성이 있습니다.

•도록 구현하는 직렬화성 합니다.

•추가 어떤 사용자 지정 예외의 속성에 도움이 될 수 있는 개발자들이 쉽게 이해할 수 있도록,처리의 예외는 더 낫습니다.

•추가하면 모든 사용자 지정성,확인을 구현하는 것과 재정의 GetObjectData 를 직렬화를 사용자 정의 속성입니다.

•추가하면 모든 사용자 지정성,재정의 메시지는 속성을 추가할 수 있도록 당신의 속성을 기준 예외 메시지입니다.

•기억을 연결하는 원래 예외를 사용하 InnerException 재산의 사용자 정의 예외는 아니다.

당신은 일반적으로 잡아 다시 던지는 두 가지 이유 중 하나에 따라 코드의 앉아 건축에서 응용 프로그램입니다.

에서 핵심 응용 프로그램의 일반적으로 잡아 다시 throw 을 번역하는 예외로 더 많은 뭔가 의미가 있습니다.예를 들어 쓰는 경우에 데이터 액세스 층을 사용하여 사용자정의 오류 코드 SQL Server,할 수 있습 번역 SqlException 것으로 다음과 같 ObjectNotFoundException.이기 때문에 유용(a)그것은 그것을 쉽게 호출을 처리하는 특정 유형의 예외는 아니다,그리고(b)그것을 방지하기 때문에 구현의 상세 정보는 레이어와 같은 사실 당신은 SQL 을 사용하여 서버에 대한 지속성을 위해 누출로 다른 레이어를 변경할 수 있는 일들이 미래에 더 쉽게입니다.

에서의 경계를 응용 프로그램은 그것의 일반적인을 잡고 다시 던져 번역하지 않는 예외 그래서 로그인할 수 있는 그것의 세부 사항,원조에 디버깅하고 진단하는 데 라이브 문제입니다.이상적으로 당신이 원하는 게시하는 오류가 발생하는 운영 팀을 수 있습니다(예:이벤트 로그)뿐만 아니라 어딘가에게 문맥 주위에 어디에서 예외가 발생하 제어 흐름에 대한 개발자(일반적으로 추적하).

나는 생각할 수 있는 다음과 같은 이유:

  • 을 유지하의 던지는 예외 유형을 고정의 일환으로,API,그래서만 호출자에게 고민해야에 대한 고정 설정의 예외가 있습니다.자바에서,당신은 실제적으로 그렇게 때문에 선택된 예외 메커니즘이 있습니다.

  • 추가 어떤 상황에 맞는 정보는 예외입니다.예를 들어,시키는 대신 베어"레코드를 찾을 수 없습니다."를 통해 전달에서 DB 할 수 있습니다 그것을 잡을 추가"...처리 순서 아 XXX 을 찾고,제품 YYY".

  • 일부 정리 파일을 닫,회전시의 거래를 확보,일부 처리합니다.

일반적으로"뭔가"하나는 포함한 더 나은 설명하는 예외(예를 들어,포장에 그것의 또 다른 예외),또는 정보를 추적을 통해 일정한 소스입니다.

또 다른 가능성은 경우에는 예외로 입력하지 않는 충분한 정보를 알고 있는 경우에는 예외가 필요하다 잡은 어떤 경우에는,잡고 그것을 검사한 자세한 정보를 제공할 것입니다.

이것은 말을 하지 않습 방법을 사용에 대한 순수하게 좋은 이유로,많은 시간 때 사용하는 개발자가 생각하는 추적 정보는 필요할 수 있습니다 미래의 어느 시점에서,어떤 경우에 당신은 try{}catch{던져;}스타일 모두에 도움이 되지 않는다.

생각에 따라 달라집을 하려는 당신이 무엇을 할 예외는 아니다.

좋은 이유 중 하나는 것을 로그에 오류가 처음에 잡고 그것을 던져 최대 UI 를 생성하는 친절한 오류 메시지를 표시 할 수있는 옵션을 더"/고급 상세보기"오류를 포함하는 원 오류가 있습니다.

또 다른 방법은"다시 시도"접근 방식은,예를 들면,오류가 횟수가 유지되고,후 일정 금액을 재시도 횟수는 시간은 오류를 발송까지 스택(이것은 때때로 수행에 대한 데이터베이스에 대한 액세스는 데이터베이스는 호출 시간 제한 또는 웹 서비스에 액세스 속도가 느린 네트워크를 통해).

무리가있을 것 다른 이유로 그것을 하지만.

참고로,이와 관련된 질문에 대한 각 유형의 재 던져:성능에 대한 고려사항을 던지는 예외

나의 질문에 초점을 맞추고"왜"우리는 다시 예외가 발생하고 그 사용은 응용 프로그램에서는 예외 처리 전략입니다.

시작할 때까지 사용하여 EntLib ExceptionBlock,내가 그들을 사용하여 로그에 오류를 던지기 전에.어떤 생각할 때 나는 취급할 수 있는지만,시간이었다 더 나은 그들을 더럽게 실패에 UAT(로그인 한 후 그들)보다는 오히려 커버 흐름에는 버그입니다.

응용 프로그램은 대부분의 아마 사람들을 잡기서 다시 발생한 예외 높은 호출 스택에 그래서 다시 그들에게 던지는 것을 허용하는 최대 높은 핸들러를 차단 및 공정들을 적절하게 합니다.그것은 매우 일반적 응용을 위해 최고 수준의 예외 처리기 기록이나 보고 expections.

또 다른 대안은 coder 과를 잡는 대신 그냥 설정의 예외를 그들이 원하는 처리하는 그들을 잡은 것이고 그 다음 다시 발생한 것만 그들은 실제로 처리합니다.

로 Rafal 언급하고,때로는 이렇게 변환하는 확인된 예외를 선택하지 않은 제외,또는 확인하는 예외의 더 적합한 API 를 사용합니다.가 여기 예를 들어:

http://radio-weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html

에서 보면 예외로 로 얻을 수있는 또 다른 방법이있는 방법 결과, 다시 던지는 예외는 다음과 같 포장의 결과로 일부 다른 객체입니다.

그리고 이것은 일반적인 작업이 아닌 특별하다.일반적으로 이 일에 국경의 두 응용 프로그램 레이어-면에서 함수층 B 함수를 호출에서 레이어 C,변환 C's 결과로 B'의 내부 형태입니다.

A -- calls --> B -- calls --> C

지 않는 경우,그 다음에 레이어 A 는 레이어 B 가 될 것입의 전체 세트 JDK 예외 처리합니다.:-)

으로도 허용되는 답변이 지,층 A 지 않을 수도 있습도 인식 C의 예외입니다.

,servlet:검색 이미지와 그것의 메타 정보
층 B, JPEG 라이브러리:를 수집할 수 있 DCIM 태그를 분석하 JPEG 파일
층 C, 간단한 DB:클래 독서 문자열에 기록에서의 랜덤 액세스 파일입니다.일부 바이트가 깨진,그래서 그것은 예외가 발생하는 말"읽을 수 없습니다 UTF-8 개 문자열에 기록'bibliographicCitation'".

그래서 A 지 않습의 의미를 이해하기 위해'bibliographicCitation'.그래서 B 번역해야 하는 이에 대 한 예외를 ATagsReadingException 을 감싸는 원래이다.

의 주된 이유는 재 던지는 예외를 호출 스택 손길이 닿지 않은,그래서 당신은 당신을 더 얻을 수 있습의 완전한 그림을 어떻게 호출 시퀀스입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top