spring-projects/spring-framework · error · AopConfigException
At least one handler method must be found in class [{throwsA
Error message
At least one handler method must be found in class [{throwsAdvice.getClass()}] What it means
After scanning all public methods, if no compliant afterThrowing handler was registered (the map is empty), ThrowsAdviceInterceptor refuses to construct - an exception handler with no handlers is meaningless. AopConfigException is thrown naming the advice class.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/framework/adapter/ThrowsAdviceInterceptor.java:119
}
if (throwableParam == null) {
throw new AopConfigException("Unsupported afterThrowing signature: single throwable argument " +
"or four arguments Method, Object[], target, throwable expected: " + method);
}
// An exception handler to register...
Method existingMethod = this.exceptionHandlerMap.put(throwableParam, method);
if (existingMethod != null) {
throw new AopConfigException("Only one afterThrowing method per specific Throwable subclass " +
"allowed: " + method + " / " + existingMethod);
}
if (logger.isDebugEnabled()) {
logger.debug("Found exception handler method on throws advice: " + method);
}
}
}
if (this.exceptionHandlerMap.isEmpty()) {
throw new AopConfigException(
"At least one handler method must be found in class [" + throwsAdvice.getClass() + "]");
}
}
/**
* Return the number of handler methods in this advice.
*/
public int getHandlerMethodCount() {
return this.exceptionHandlerMap.size();
}
@Override
public @Nullable Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}View on GitHub (pinned to e8729d0438)
Solutions
- Declare at least one public afterThrowing method with a valid 1- or 4-arg signature.
- Ensure the method is public (getMethods() returns only public methods).
- Check the exact spelling: method must be named 'afterThrowing'.
Example fix
// before
class MyAdvice implements ThrowsAdvice { /* no methods */ }
// after
class MyAdvice implements ThrowsAdvice {
public void afterThrowing(Exception ex) { log(ex); }
} Defensive patterns
Strategy: validation
Validate before calling
long n = java.util.Arrays.stream(advice.getClass().getMethods())
.filter(m -> m.getName().equals("afterThrowing")
&& (m.getParameterCount() == 1 || m.getParameterCount() == 4)
&& java.lang.reflect.Modifier.isPublic(m.getModifiers()))
.count();
if (n == 0) throw new IllegalStateException(advice.getClass() + " implements ThrowsAdvice but defines no valid afterThrowing method"); Type guard
public static boolean hasValidAfterThrowing(Class<?> adviceClass) {
return java.util.Arrays.stream(adviceClass.getMethods())
.anyMatch(m -> m.getName().equals("afterThrowing")
&& (m.getParameterCount() == 1 || m.getParameterCount() == 4));
} Prevention
- Implement at least one public afterThrowing method on every ThrowsAdvice class.
- Verify exact method name spelling and public visibility.
- Add a unit test that constructs ThrowsAdviceInterceptor for each advice class at build time.
When it happens
Trigger: Implementing the marker interface org.springframework.aop.ThrowsAdvice without declaring any afterThrowing method; declaring handlers with invalid signatures (so all were rejected before reaching registration, though those throw earlier) or with the wrong method name.
Common situations: Empty marker implementation used as a placeholder; typo in method name ('afterthrowing', 'after_Throwing'); methods made non-public so getClass().getMethods() does not see them.
Related errors
- Invalid afterThrowing signature: single argument must be a T
- Invalid afterThrowing signature: four arguments must be Meth
- Unsupported afterThrowing signature: single throwable argume
- Only one afterThrowing method per specific Throwable subclas
- Class '{}' is not an @AspectJ aspect
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/dda5463ab340a8cb.json.
Report an issue: GitHub.