public Mono<UserFriendRequest> authAndRecallFriendRequest(
            @NotNull Long requesterId,
            @NotNull Long requestId) {
        try {
            Validator.notNull(requesterId, "requesterId");
            Validator.notNull(requestId, "requestId");
        } catch (ResponseException e) {
            return Mono.error(e);
        }
        if (!allowRecallPendingFriendRequestBySender) {
            return Mono.error(
                    ResponseException.get(ResponseStatusCode.RECALLING_FRIEND_REQUEST_IS_DISABLED));
        }
        return queryRequesterIdAndRecipientIdAndCreationDateAndStatus(requestId)
                // If the requester is not authorized to the request,
                // they should not know the status of the request from the error code.
                // So we should not tell if the request exists or not.
                .switchIfEmpty(
                        ResponseExceptionPublisherPool.notFriendRequestSenderToRecallRequest())
                .flatMap(request -> {
                    // If the requester is not authorized to the request,
                    // they should not know the status of the request from the error code.
                    // So we check whether the requester is authorized first.
                    if (!requesterId.equals(request.getRequesterId())) {
                        return ResponseExceptionPublisherPool
                                .notFriendRequestSenderToRecallRequest();
                    }
                    RequestStatus status = request.getStatus();
                    if (status == RequestStatus.PENDING) {
                        if (userFriendRequestRepository.isExpired(request.getCreationDate()
                                .getTime())) {
                            return Mono.error(ResponseException.get(
                                    ResponseStatusCode.RECALL_NON_PENDING_FRIEND_REQUEST,
                                    "The request is under the status "
                                            + RequestStatus.EXPIRED));
                        }
                    } else {
                        return Mono.error(ResponseException.get(
                                ResponseStatusCode.RECALL_NON_PENDING_FRIEND_REQUEST,
                                "The request is under the status "
                                        + status));
                    }
                    return userFriendRequestRepository
                            .updateStatusIfPending(requestId, RequestStatus.CANCELED, null, null)
                            .flatMap(result -> result.getModifiedCount() == 0
                                    // Though it may return empty because the request had been
                                    // deleted between the status check,
                                    // but only admins can delete them, and it is really rare.
                                    // So we handle these cases as if the status of the request has
                                    // changed.
                                    ? Mono.error(ResponseException.get(
                                            ResponseStatusCode.RECALL_NON_PENDING_FRIEND_REQUEST))
                                    : Mono.whenDelayError(userVersionService
                                            .updateReceivedFriendRequestsVersion(
                                                    request.getRecipientId())
                                            .onErrorResume(t -> {
                                                LOGGER.error(
                                                        "Caught an error while updating the received friend requests version of the recipient ({}) after recalling a friend request",
                                                        request.getRecipientId(),
                                                        t);
                                                return Mono.empty();
                                            }),
                                            userVersionService
                                                    .updateSentFriendRequestsVersion(
                                                            request.getRequesterId())
                                                    .onErrorResume(t -> {
                                                        LOGGER.error(
                                                                "Caught an error while updating the sent friend requests version of the requester ({}) after recalling a friend request",
                                                                request.getRequesterId(),
                                                                t);
                                                        return Mono.empty();
                                                    })))
                            .thenReturn(request);
                });
    }
@return The requester ID, recipient ID, creation date and status.
turms-service/src/main/java/im/turms/service/domain/user/service/UserFriendRequestService.java