Issue
While experimenting with asynchronous processing, I discovered an unusual phenomenon.
@Slf4j
@ControllerAdvice
public class ErrorAdvice {
@ExceptionHandler(Exception.class)
public void ex(Exception e) {
log.info("error e = ", e);
}
@ExceptionHandler(CompletionException.class)
public void ex2(CompletionException e) {
log.info("error e = ", e);
}
}
@Service
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
@Transactional
public void save(String name) {
memberRepository.save(new Member(name));
throw new IllegalStateException();
}
}
public class Client {
@Transactional
public void save(String name) {
CompletableFuture.runAsync(() -> memberService.save(name));
}
}
Client starts a transaction and CompletableFuture starts another thread, thus starting a newly bound transaction scope.
But the problem is that I can't catch the error in ControllerAdvice. Now I think it's very risky in real application operation. What is the cause and how to fix it?
In my opinion, ControllerAdvice wraps the controller as a proxy, so even if Memberservice does asynchronous processing, it doesn't make sense that the exception is not handled because it is inside the proxy. It doesn't even leave any logs. Why is the exception being ignored??
Solution
why are you using CompletableFuture.runAsync(() -> memberService.save(name));
?
just try memberService.save(name));
Answered By - Rafael da Silva
Answer Checked By - Katrina (JavaFixing Volunteer)