{"record":{"id":"7ace6b6180ba2a12","repo":"spring-projects/spring-framework","slug":"only-afterthrowing-advice-can-be-used-to-bind-a-th","errorCode":null,"errorMessage":"Only afterThrowing advice can be used to bind a thrown exception","messagePattern":"Only afterThrowing advice can be used to bind a thrown exception","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java","lineNumber":326,"sourceCode":"\t\t\t}\n\t\t\tcatch (Throwable ex) {\n\t\t\t\tthrow new IllegalArgumentException(\"Returning name '\" + name +\n\t\t\t\t\t\t\"' is neither a valid argument name nor the fully-qualified \" +\n\t\t\t\t\t\t\"name of a Java type on the classpath. Root cause: \" + ex);\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected Class<?> getDiscoveredReturningType() {\n\t\treturn this.discoveredReturningType;\n\t}\n\n\tprotected @Nullable Type getDiscoveredReturningGenericType() {\n\t\treturn this.discoveredReturningGenericType;\n\t}\n\n\tpublic void setThrowingName(String name) {\n\t\tthrow new UnsupportedOperationException(\"Only afterThrowing advice can be used to bind a thrown exception\");\n\t}\n\n\t/**\n\t * We need to hold the throwing name at this level for argument binding calculations,\n\t * this method allows the afterThrowing advice subclass to set the name.\n\t */\n\tprotected void setThrowingNameNoCheck(String name) {\n\t\t// name could be a variable or a type...\n\t\tif (isVariableName(name)) {\n\t\t\tthis.throwingName = name;\n\t\t}\n\t\telse {\n\t\t\t// assume a type\n\t\t\ttry {\n\t\t\t\tthis.discoveredThrowingType = ClassUtils.forName(name, getAspectClassLoader());\n\t\t\t}\n\t\t\tcatch (Throwable ex) {\n\t\t\t\tthrow new IllegalArgumentException(\"Throwing name '\" + name +","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java#L308-L344","documentation":"The base AbstractAspectJAdvice.setThrowingName(String) at line 325-327 always throws UnsupportedOperationException. Only AspectJAfterThrowingAdvice overrides it to delegate to setThrowingNameNoCheck. Binding a thrown exception is semantically valid only for after-throwing advice, so every other advice type refuses it.","triggerScenarios":"Calling setThrowingName(\"ex\") on an instance of AspectJMethodBeforeAdvice, AspectJAroundAdvice, or AspectJAfterReturningAdvice, or configuring a 'throwing' attribute on <aop:before>, <aop:around>, or <aop:after-returning>. Also triggered by a generic programmatic registrar that always sets throwing.","commonSituations":"XML/annotation config where a 'throwing=\"...\"' attribute lands on the wrong advice element, or a shared advisor builder that unconditionally calls setThrowingName. Typical when copying an after-throwing block and forgetting to change the advice kind.","solutions":["Move the 'throwing' binding to an @AfterThrowing / <aop:after-throwing> advice — the only type that supports it.","Remove the 'throwing' attribute from the offending before/around/after-returning element.","If registering programmatically, guard setThrowingName with an instanceof AspectJAfterThrowingAdvice check."],"exampleFix":"// before — throwing on after-returning (invalid)\n<aop:after-returning method=\"after\"\n    pointcut=\"execution(* *(..))\" throwing=\"ex\"/>\n\n// after — use after-throwing advice to bind the exception\n<aop:after-throwing method=\"onError\"\n    pointcut=\"execution(* *(..))\" throwing=\"ex\"/>","handlingStrategy":"type-guard","validationCode":"import org.springframework.aop.aspectj.AspectJAfterThrowingAdvice;\n\nvoid safeSetThrowingName(AbstractAspectJAdvice advice, String name) {\n    if (advice instanceof AspectJAfterThrowingAdvice) {\n        advice.setThrowingName(name);\n    } else {\n        throw new IllegalStateException(\"throwing binding requires AspectJAfterThrowingAdvice\");\n    }\n}","typeGuard":"boolean supportsThrowingBinding(AbstractAspectJAdvice advice) {\n    return advice instanceof org.springframework.aop.aspectj.AspectJAfterThrowingAdvice;\n}","tryCatchPattern":"try {\n    advice.setThrowingName(\"ex\");\n} catch (UnsupportedOperationException ex) {\n    // throwing is only valid for afterThrowing advice; remove the attribute\n}","preventionTips":["Apply 'throwing' only to @AfterThrowing / <aop:after-throwing>.","Branch on concrete advice type in programmatic registrars.","Re-check XML after converting between advice types."],"tags":["spring-aop","aspectj","after-throwing","advice-type","configuration"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}