public Mono<GroupJoinRequest> authAndRecallPendingGroupJoinRequest(
            @NotNull Long requesterId,
            @NotNull Long requestId) {
        try {
            Validator.notNull(requesterId, "requesterId");
            Validator.notNull(requestId, "requestId");
        } catch (ResponseException e) {
            return Mono.error(e);
        }
        if (!allowRecallPendingJoinRequestBySender) {
            return Mono.error(ResponseException
                    .get(ResponseStatusCode.RECALLING_GROUP_JOIN_REQUEST_IS_DISABLED));
        }
        return queryRequesterIdAndStatusAndGroupId(requestId)
                // If the requester is not authorized to the join request,
                // they should not know the status of the join request from the error code.
                // So we should not tell if the request exists or not.
                .switchIfEmpty(
                        ResponseExceptionPublisherPool.notGroupJoinRequestSenderToRecallRequest())
                .flatMap(request -> {
                    // If the requester is not authorized to the join request,
                    // they should not know the status of the join request from the error code.
                    // So we check whether the requester is authorized first.
                    if (!request.getRequesterId()
                            .equals(requesterId)) {
                        return ResponseExceptionPublisherPool
                                .notGroupJoinRequestSenderToRecallRequest();
                    }
                    RequestStatus status = request.getStatus();
                    if (status != RequestStatus.PENDING) {
                        String reason = "The request is under the status "
                                + status;
                        return Mono.error(ResponseException.get(
                                ResponseStatusCode.RECALL_NON_PENDING_GROUP_JOIN_REQUEST,
                                reason));
                    }
                    return groupJoinRequestRepository
                            .updateStatusIfPending(requestId,
                                    RequestStatus.CANCELED,
                                    requesterId,
                                    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_GROUP_JOIN_REQUEST))
                                    : Mono.whenDelayError(groupVersionService
                                            .updateJoinRequestsVersion(request.getGroupId())
                                            .onErrorResume(t -> {
                                                LOGGER.error(
                                                        "Caught an error while updating the join requests version of the group ({}) after recalling a pending join request",
                                                        request.getGroupId(),
                                                        t);
                                                return Mono.empty();
                                            }),
                                            userVersionService
                                                    .updateSentGroupJoinRequestsVersion(requesterId)
                                                    .onErrorResume(t -> {
                                                        LOGGER.error(
                                                                "Caught an error while updating the sent join requests version of the requester ({}) after recalling a pending join request",
                                                                requesterId,
                                                                t);
                                                        return Mono.empty();
                                                    }))
                                            .thenReturn(request));
                });
    }
@return requester ID, group ID, and status
turms-service/src/main/java/im/turms/service/domain/group/service/GroupJoinRequestService.java