springframework.data.mongodb: Error Handling with Spring Data and Mongo Java Driver

Viewed 16

I have java application with using Spring-Data. I need to use a resumeToken for cases where an exception will occur when the change stream listener is running. Now I'm simulating the occurrence of an exception manually.

When I try to simulate an exception and throw it from userListener() method, it gets into the createListener() method catch block, but it doesn't get into the register() method catch block, where I could apply it.

Method with listener functionality. This is where I'm throwing the exception manually for my test:

private MessageListener<ChangeStreamDocument<Document>, User> userListener() throws Exception {
    return createListener(new CallbackChangeStream<User>() {
        @Override
        public void insert(ChangeStreamDocument<Document> raw, User body) {
            log.info("new user is inserted, content is {}.", body.toString());
            throw new MongoCommandException(raw.getResumeToken(), new ServerAddress());
        }
    });
}

The method from where the mongo change stream event listener is called depending on the operation type. The exception is caught in the catch block of this method:

private <T> MessageListener<ChangeStreamDocument<Document>, T> createListener(CallbackChangeStream<T> callback) {
    return listenMsg -> {
        ChangeStreamDocument<Document> raw = listenMsg.getRaw();
        OperationType operationType = Objects.requireNonNull(raw).getOperationType();
        try {
            switch (operationType) {
                case INSERT: callback.insert(raw, listenMsg.getBody());
                default: break;
            }
        } catch (MongoCommandException e) {
            throw e;
        }
    };
}
public interface CallbackChangeStream<T> {
    void insert(ChangeStreamDocument<Document> raw, T body);
}

Methods where I can apply resumeToken in case the catch block is triggered. But the exception is not being caught here:

private <T> void registerListener(
        String collectionName,
        MessageListener<ChangeStreamDocument<Document>, T> listener,
        Class<T> bodyType,
        Optional<BsonDocument> resumeToken
) {
    ChangeStreamOptions.ChangeStreamOptionsBuilder builder = ChangeStreamOptions.builder().returnFullDocumentOnUpdate();
    if (resumeToken.isPresent()) {
        builder.resumeToken(resumeToken.get());
    }
    registerListener(collectionName, listener, bodyType, builder.build());
}

public void register(BsonDocument token) {
    boolean ignoreLastResumeToken = false;
    do {
        try {
            registerListener("user", userListener(), User.class, token);
            ignoreLastResumeToken = false;
        } catch (MongoCommandException e) {
            ignoreLastResumeToken = true;
        }
    } while (ignoreLastResumeToken);
}

My imports:

import org.bson.Document
import com.mongodb.client.model.changestream.ChangeStreamDocument
import org.springframework.context.ApplicationEventPublisher
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.messaging.MessageListener

My exception stackTrace:


Exception in thread "SimpleAsyncTaskExecutor-1" com.mongodb.MongoCommandException: Command failed with error -1: '' on server 127.0.0.1:27017. The full response is { "_data" : "82631AABD60000001F2B022C0100296E5A1004A257E76C43E64F0DA263D1282932AA1046645F696400646313BE07AD57A0ECFE5FBBBD0004" }
    at com.demo.web.ChangeStreamListener$1.update(ChangeStreamListener.java:85)
    at com.demo.web.ChangeStreamListener$1.update(ChangeStreamListener.java:74)
    at com.demo.web.ChangeStreamListener.lambda$createMessageListener$0(ChangeStreamListener.java:144)
    at org.springframework.data.mongodb.core.messaging.CursorReadingTask.emitMessage(CursorReadingTask.java:222)
    at org.springframework.data.mongodb.core.messaging.CursorReadingTask.run(CursorReadingTask.java:85)
    at java.base/java.lang.Thread.run(Thread.java:833)

How can I catch the exception in order to use the resumeToken ?

0 Answers
Related