简体   繁体   中英

Handling CompletableFuture exceptions in controller

I'm trying to get into CompletableFuture class for a project I'm running, and I got to some question here:

There is the following method: it tries to find a conversation by its ID or hash; and, if not found, it throws an exception. So far, so good.

public ConversationOutput getConversationByIdOrHash(String conversationIdOrHash)
            throws ConversationNotFoundException {
        Conversation conversation = this.conversationRepository.getByIdOrHash(conversationIdOrHash);

        if (conversation == null) {
            throw new ConversationNotFoundException(conversationIdOrHash);
        }

        return this.modelMapper.map(conversation, ConversationOutput.class);
    }

Note that I am throwing ConversationNotFoundException from my method signature. My SpringBoot controller is reacting to this exception and it's all working fine since the beginning.

What I'm trying to do is to make this to a CompletableFuture return and actually throwing an exception, something similar to:

    public CompletableFuture<ConversationOutput> getConversationByIdOrHashAsync(String conversationIdOrHash)
            throws ConversationNotFoundException {
        return CompletableFuture.supplyAsync(() -> this.getConversationByIdOrHash(conversationIdOrHash));
}

I've seen posts where people use exceptionally to handle exceptions, but what I really want to do is to throw it to my controller and let it handle it. Any suggestions of how can I make it?

Thank you all!

The question is do you care about the result of CompletableFuture . CompletableFuture is like a special task and it is processed on other thread. If you don't invoke .join() you won't receive the results of CompletableFuture . This method also will propagate the exception if any occured. However it waits for CompletableFuture to finish and blocks the request. However, there is no way to get exceptions from the inside of the CompletableFuture without waiting, you have to treat it like other task.

You can pass the completed future in case of a success, and failed future along with your custom exception.

public CompletableFuture<ConversationOutput> getConversationByIdOrHashAsync(String conversationIdOrHash) {
        try {
            return CompletableFuture.completedFuture(this.getConversationByIdOrHash(conversationIdOrHash));
        } catch (ConversationNotFoundException e) {
            return CompletableFuture.failedFuture(e);
        }
    }

and then at your controller level you can handle the exception.

final CompletableFuture<ConversationOutput> future = getConversationByIdOrHashAsync("idOrHash");
        future.whenComplete((r, e) -> {
            if (e != null) {
                if (e instanceof ConversationNotFoundException) {
                    //handling
                }
            }
        });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM