MongoDB重复键异常无法被代码捕获的原因排查
异步执行导致异常脱离当前线程:如果调用Repository插入方法的代码是异步执行的(比如标记了
@Async注解),异常会在异步线程中抛出,当前线程的try-catch块根本捕获不到。这种情况需要在异步方法内部处理异常,或者通过CompletableFuture的回调逻辑来捕获。异常被框架包装为未捕获的类型:Spring Data MongoDB有时会把底层的
MongoWriteException包装成DataIntegrityViolationException而非DuplicateKeyException,如果你的捕获逻辑没覆盖这个类型,就会出现异常漏捕的情况。可以尝试添加DataIntegrityViolationException的捕获块验证。使用Reactive编程模型未正确处理异常:如果用的是
ReactiveMongoRepository,插入操作返回Mono/Flux类型,普通的try-catch无法捕获异步流中的异常,必须通过onErrorResume、onErrorReturn等Reactive操作符处理,或者调用block()/subscribe()时包裹try-catch。事务上下文导致异常延迟抛出:如果插入操作在事务中执行,异常可能不会在调用插入方法时立即抛出,而是在事务提交时才触发。如果你的try-catch只包裹了插入方法的调用,没覆盖事务提交的逻辑,自然捕获不到异常。
批量插入场景下异常被封装而非抛出:部分版本的Mongo驱动或Spring Data在批量插入时,不会直接抛出异常,而是将错误信息封装在返回的结果对象中,此时需要主动检查结果中的错误状态,而非依赖try-catch捕获。
内容的提问来源于stack exchange,提问作者jaya sinha

