2012-04-13 3 views
3

코드로 시작합니다. 이것은 하나의 반사리플렉션에 의해 호출 된 메소드의 RuntimeException 전달

try { 
    Method method = states.getClass().getDeclaredMethod(
      getCurrentStateId() + "_" + request.getEvent()); 
    states.setData(request, dataManager); 
    method.invoke(states); 
} catch (NoSuchMethodException e) { 
    logger.debug("Method " + getCurrentStateId() + "_" + request.getEvent() 
      + " cannot be found - invocation not performed.", e); 
} catch (IllegalArgumentException e) { 
    throw new InternalException("Method invocation with reflection failed.", e); 
} catch (IllegalAccessException e) { 
    throw new InternalException("Method invocation with reflection failed.", e); 
} catch (InvocationTargetException e) { 
    throw new InternalException("Method invocation with reflection failed.", e); 
} 

을 사용하는 방법을 호출하고 PropertiesDontMatchException (런타임) 발생 다음 코드로 메소드를 호출합니다.

... 
if (totalCredits < minimumCredits || totalCredits > maximumCredits) { 
    throw new PropertiesDontMatchException("Minimum amount of credits=" + minimumCredits 
      + ", maximum amount of credits=" + maximumCredits + ". Your amount of credits="     + totalCredits + ". You have to modify your set of subjects."); 
} 
... 

것은 내 런타임 예외가 InvocationTargetException에 랩과 제 코드에 걸려되고 있다는 점이다. 이것은 내가 원하는 것이 아닙니다. 그러나 문서에 따르면, 그것은 올바른 행동입니다.

그래서 나는이 솔루션

... 
} catch (InvocationTargetException e) { 
    if (e.getCause() instanceof PropertiesDontMatchException) { 
     throw (PropertiesDontMatchException) e.getCause(); 
    } 
    throw new InternalException("Method invocation with reflection failed.", e); 
} 
... 

이 내 런타임 예외를 전파 또는이 문제의 더 나은 솔루션이하는 방법을 적절한 방법인가를 내놓았다?

답변

4

예,이 경우 올바른 오류 처리입니다.

} catch (InvocationTargetException e) { 
    if (e.getCause() instanceof RuntimeException) { 
     throw (RuntimeException) e.getCause(); 
    } 
    if (e.getCause() instanceof Error) { 
     throw (Error) e.getCause(); 
    } 
    throw new InternalException("Method invocation with reflection failed.", e); 
} 

을 또는 확인 예외를 대신 사용자 정의 InternalExceptionRuntimeException를 사용하여 상관 없어 대신하는 경우 에서 Throwables utility class을 사용합니다 : 난 단지 어떤 RuntimeException에 대한 테스트를 확장 할

} catch (InvocationTargetException e) { 
    throw Throwables.propagate(e.getCause()); 
} 

여분의 포장은 예를 들면 귀하의 방법은 던지고 IllegalAccessException 및 반사 메커니즘 자체가 그것을 던지고.

비슷한 API 디자인 선택은 Future.get()에서 볼 수 있습니다. - 비동기 작업에서 던져진 예외의 경우 ExecutionException이 던져져 실제 예외를 래핑합니다.

+0

다른 런타임 예외를 InternalException에 랩 한 다음 클라이언트에 500 내부 오류로 반환하기 때문에이 작업을 수행 할 수 없습니다. Properties..Exception은 400 잘못된 요청으로 반환됩니다. 하지만 대답을 주셔서 감사합니다 ... – user219882

+0

만약'e.getCause() instanceof Error'? – Saintali

+0

@Saintali : 당신 말이 맞아요, 내 대답을 업데이 트하고 구아바 팁을 추가했습니다. 감사! –

관련 문제