IT박스

자세한 메시지로 근본 원인을 찾기 위해 예외 getCause ()를 반복하는 방법

itboxs 2020. 11. 26. 08:04
반응형

자세한 메시지로 근본 원인을 찾기 위해 예외 getCause ()를 반복하는 방법


이 질문에 이미 답변이 있습니다.

saveOrUpdate()데이터를 저장하기 위해 최대 절전 모드 를 호출하려고합니다 . 열에는 고유 인덱스가 있으므로 ConstraintViolationExceptionEclipse 디버거를 통해 살펴볼 때 발생합니다.

테이블에 데이터를 삽입하는 동안 예외에 따라 근본 원인이 다를 수 있기 때문입니다. 예외의 근본 원인과 메시지를 확인하기 위해
루프 / 순회하는 방법을 알고 싶었습니다 getCause().

업데이트 :
친절한 응답에 감사드립니다. 아래 이미지와 같은 출력을 원합니다 . detailMessage 필드
여기에 이미지 설명 입력
에 액세스해야 합니다. (제 질문을 더 명확하게 할 수 없다면 정말 죄송합니다.)

감사.


Apache ExceptionUtils 는 다음 방법을 제공합니다.

Throwable getRootCause(Throwable throwable) 

만큼 잘

String getRootCauseMessage(Throwable th) 

나는 일반적으로 Apache의 구현 대신 아래 구현을 사용합니다.

복잡성 외에도 Apache의 구현은 원인이 발견되지 않으면 null을 반환하므로 null에 대한 추가 검사를 수행해야합니다.

일반적으로 예외의 근본 / 원인을 찾을 때 시작해야 할 null이 아닌 예외가 이미 있습니다. 이는 더 깊은 원인을 찾을 수없는 경우 모든 의도 된 제안에 대한 실패의 원인입니다.

Throwable getCause(Throwable e) {
    Throwable cause = null; 
    Throwable result = e;

    while(null != (cause = result.getCause())  && (result != cause) ) {
        result = cause;
    }
    return result;
}

Java 8 Stream API를 사용하면 다음을 수행 할 수 있습니다.

Optional<Throwable> rootCause = Stream.iterate(exception, Throwable::getCause)
                                      .filter(element -> element.getCause() == null)
                                      .findFirst();

이 코드는 예외 원인 루프에 영향을받지 않으므로 프로덕션에서 피해야합니다.


이와 같은 것을 요구하고 있습니까?

Throwable cause = originalException;
while(cause.getCause() != null && cause.getCause() != cause) {
    cause = cause.getCause();
}

아니면 내가 뭔가 빠졌나요?


GuavaThrowables 는 다음과 같은 방법을 제공합니다.

Throwable getRootCause(Throwable throwable)

만큼 잘

String getStackTraceAsString(Throwable throwable)

} catch (Exception ex) {
    while (ex.getCause() != null)
        ex = ex.getCause();
    System.out.println("Root cause is " + ex.getMessage());
}

더 복잡한 것을 기대 했습니까?


에서 APACHE ; 구현은 아래와 같습니다.

하이라이트는 list.contains (throwable) == false입니다.

public static Throwable getRootCause(final Throwable throwable) {
    final List<Throwable> list = getThrowableList(throwable);
    return list.size() < 2 ? null : (Throwable)list.get(list.size() - 1);
}

public static List<Throwable> getThrowableList(Throwable throwable) {
    final List<Throwable> list = new ArrayList<Throwable>();
    while (throwable != null && list.contains(throwable) == false) {
        list.add(throwable);
        throwable = ExceptionUtils.getCause(throwable);
    }
    return list;
}

이 함수를 Util 클래스에 넣을 수 있습니다.

public static Throwable getRootException(Throwable exception){
 Throwable rootException=exception;
 while(rootException.getCause()!=null){
  rootException = rootException.getCause();
 }
 return rootException;
}

사용 예 :

catch(MyException e){
  System.out.println(getRootException(e).getLocalizedMessage());
}

출처 : 예외의 루트 예외를 얻는 방법


재귀 적으로 :

public static Throwable getRootCause(Throwable e) {
    if (e.getCause() == null) return e;
    return getRootCause(e.getCause());
}

참고 URL : https://stackoverflow.com/questions/17747175/how-can-i-loop-through-exception-getcause-to-find-root-cause-with-detail-messa

반응형