skip to content

@AfterThrowing Advice

@AfterThrowing fires when the join point throws, binds the exception, can be filtered by exception type, and rethrows rather than swallowing it. Useful for translation and alerting, and interviewers check that you know it does not suppress the error.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is @AfterThrowing advice in Spring AOP and when does it run?

level: juniorimportance: must knowfreq 65%

answer

  1. Runs only on exceptional exit
  2. Observe-only, doesn't swallow
  3. Proxy-based, one of 5 advice types
  4. @AfterReturning = normal, @After = finally

basics

~10 s

@AfterThrowing is an aspect advice method that runs only when the matched method (join point) exits by throwing an exception. If the method returns normally, it does not run.

solid answer

~40 s

@AfterThrowing is one of Spring AOP's advice types (alongside @Before, @After, @AfterReturning, and @Around). You annotate a method in an @Aspect class with @AfterThrowing and a pointcut. Spring wraps the target bean in a proxy; when a matched method is invoked and throws an exception, the proxy invokes your advice AFTER the exception is thrown but before it propagates to the caller. It runs only on the exceptional exit path — never when the method returns normally. Crucially, @AfterThrowing observes the exception; it does not stop propagation, so the original exception still reaches the caller. Typical uses are cross-cutting logging, metrics, or alerting on failures. Because it relies on a proxy, it only intercepts calls that go through the Spring-managed bean, not internal self-invocations.

code

java · 10 lines
java
@Aspect
@Component
public class FailureLoggingAspect {
    private static final Logger log = LoggerFactory.getLogger(FailureLoggingAspect.class);

    @AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex")
    public void logFailure(JoinPoint jp, Throwable ex) {
        log.warn("{} threw {}", jp.getSignature().toShortString(), ex.toString());
    }
}

go deeper

for a junior

Must know it runs only when the method throws, and that it's proxy-based.

for a middle

Should contrast with @AfterReturning/@After and know it doesn't swallow.

for a senior

Should discuss proxy self-invocation and observe-only semantics.

for a principal

Frames it as failure observability vs @Around for recovery, plus ordering.

### What it is `@AfterThrowing` is an **advice type** in Spring AOP (Aspect-Oriented Programming). AOP lets you factor out *cross-cutting concerns* — logic like logging, security, or metrics that would otherwise be scattered across many methods — into a single reusable unit called an **aspect**. Key vocabulary: - **Aspect**: a class annotated with `@Aspect` (and usually `@Component` so Spring manages it) that holds advice. - **Join point**: a point in program execution where an aspect can act. In Spring AOP this is always a **method execution** on a Spring bean. - **Pointcut**: an expression selecting which join points to advise, e.g. `execution(* com.example.service.*.*(..))`. - **Advice**: the code that runs at a join point. `@AfterThrowing` is *after-throwing advice*. ### When it runs `@AfterThrowing` advice runs **only when the matched method exits by throwing an exception** (a Throwable propagating out). If the method returns normally, the advice does not run — that is what `@AfterReturning` is for. `@After` (the *finally* advice) runs on both paths. ### How Spring makes it work Spring AOP is **proxy-based**. When a bean is advised, Spring creates a proxy (a JDK dynamic proxy if the bean implements an interface, otherwise a CGLIB subclass proxy). Callers get the proxy. On each call the proxy runs an interceptor chain; if the underlying target method throws, the after-throwing interceptor calls your advice, then the exception continues to propagate. ### Minimal example ```java @Aspect @Component public class FailureLoggingAspect { private static final Logger log = LoggerFactory.getLogger(FailureLoggingAspect.class); @AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex") public void logFailure(JoinPoint jp, Throwable ex) { log.warn("{} failed: {}", jp.getSignature().toShortString(), ex.getMessage()); } } ``` ### Important properties - **It does not swallow the exception.** The original exception still reaches the caller. `@AfterThrowing` cannot suppress, replace, or recover from it — only observe it. To do that you need `@Around`. - **It cannot change the return value** (there is no normal return on this path). - **Proxy limitation**: only calls that pass through the proxy are intercepted. A method calling another method on `this` (self-invocation) bypasses the proxy, so the advice won't fire for the inner call. ### When to use Use `@AfterThrowing` for observe-only failure handling: logging exceptions, incrementing error counters/metrics, emitting alerts, auditing. When you need to *handle* the exception (translate, retry, return a fallback), use `@Around` instead.

  • Does @AfterThrowing stop the exception from reaching the caller?
    No. It only observes the exception; the original exception continues to propagate. To suppress or replace it you must use @Around and either not rethrow or throw a different exception.
  • Which advice runs when a method returns normally instead of throwing?
    @AfterReturning runs on normal return; @After (finally-style) runs on both normal and exceptional exit; @AfterThrowing runs only on the exceptional path.

context

open as a page

Does @AfterThrowing swallow or handle the exception? How would you actually suppress or translate it?

level: seniorimportance: must knowfreq 60%

basics

~20 s

No. @AfterThrowing only observes the exception, then the original exception keeps propagating to the caller. To suppress, replace, or recover, use @Around: catch inside proceed() and either return a fallback or throw a different exception.

open as a page

How does the throwing attribute work, and how do you filter @AfterThrowing to a specific exception type?

level: middleimportance: should knowfreq 55%

basics

~20 s

The throwing attribute names the advice method parameter that receives the thrown exception. Declaring that parameter as a specific type (e.g. DataAccessException) makes the advice fire only when the thrown exception is that type or a subtype.

open as a page

Explain advice ordering around a failure and the proxy limitations that determine whether @AfterThrowing fires at all.

level: principalimportance: should knowfreq 35%

basics

~20 s

On a throw, inner advice unwinds first: @AfterThrowing and @After run as the exception propagates back out through the proxy chain. But @AfterThrowing only fires for calls that go through the proxy — self-invocation, private/final/static methods, and swallowing @Around advice can prevent it.

open as a page

When would you choose @AfterThrowing over @ExceptionHandler / @ControllerAdvice, and vice versa?

level: middleimportance: nice to knowfreq 30%

basics

~10 s

@AfterThrowing is a general AOP hook that observes exceptions from any advised bean method but can't change the outcome. @ExceptionHandler/@ControllerAdvice is Spring MVC's mechanism to catch controller exceptions and turn them into HTTP responses.

open as a page