<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have searched the <a href="https://github.com/apache/incubator-dubbo/issues">issues</a> of this repository and believe that this is not a duplicate.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/apache/incubator-dubbo/blob/master/FAQ.md">FAQ</a> of this repository and believe that this is not a duplicate.</li>
</ul>
<h3 dir="auto">Environment</h3>
<ul dir="auto">
<li>Dubbo version: 2.7.0</li>
<li>Operating System version: 2.7.0</li>
<li>Java version: 1.8</li>
</ul>
<h3 dir="auto">Steps to reproduce this issue</h3>
<ol dir="auto">
<li>Here is demo: Here is demo: <a href="https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-mock">https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-mock</a></li>
<li>change consumer configuraton: &lt;dubbo:reference id="demoService" check="false" interface="com.alibaba.dubbo.samples.mock.api.DemoService" mock="force”/&gt;</li>
</ol>
<p dir="auto">Pls. provide [GitHub address] to reproduce this issue.</p>
<h3 dir="auto">Expected Result</h3>
<p dir="auto">force mock should be trigged.</p>
<h3 dir="auto">Actual Result</h3>
<p dir="auto">start failed.</p>
<p dir="auto">I have checked code(MockClusterInvoker) :</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Override
public Result invoke(Invocation invocation) throws RpcException {
    // ….
    else if (value.startsWith(&quot;force&quot;)) {
        if (logger.isWarnEnabled()) {
            logger.info(&quot;force-mock: &quot; + invocation.getMethodName() + &quot; force-mock enabled , url : &quot; + directory.getUrl());
        }
        //force:direct mock
        result = doMockInvoke(invocation, null);
    } 
       // ….
}"><pre class="notranslate"><span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">public</span> <span class="pl-smi">Result</span> <span class="pl-s1">invoke</span>(<span class="pl-smi">Invocation</span> <span class="pl-s1">invocation</span>) <span class="pl-k">throws</span> <span class="pl-s1">RpcException</span> {
    <span class="pl-c">// ….</span>
    <span class="pl-smi">else</span> <span class="pl-s1">if</span> (<span class="pl-s1">value</span>.<span class="pl-en">startsWith</span>(<span class="pl-s">"force"</span>)) {
        <span class="pl-k">if</span> (<span class="pl-s1">logger</span>.<span class="pl-en">isWarnEnabled</span>()) {
            <span class="pl-s1">logger</span>.<span class="pl-en">info</span>(<span class="pl-s">"force-mock: "</span> + <span class="pl-s1">invocation</span>.<span class="pl-en">getMethodName</span>() + <span class="pl-s">" force-mock enabled , url : "</span> + <span class="pl-s1">directory</span>.<span class="pl-en">getUrl</span>());
        }
        <span class="pl-c">//force:direct mock</span>
        <span class="pl-s1">result</span> = <span class="pl-en">doMockInvoke</span>(<span class="pl-s1">invocation</span>, <span class="pl-c1">null</span>);
    } 
       <span class="pl-c">// ….</span>
}</pre></div>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have searched the <a href="https://github.com/apache/dubbo/issues">issues</a> of this repository and believe that this is not a duplicate.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/apache/dubbo/blob/master/FAQ.md">FAQ</a> of this repository and believe that this is not a duplicate.</li>
</ul>
<h3 dir="auto">Environment</h3>
<ul dir="auto">
<li>Dubbo version: 2.7.3</li>
<li>Operating System version: Windows 10</li>
<li>Java version: 1.8</li>
</ul>
<h3 dir="auto">Steps to reproduce this issue</h3>
<ol dir="auto">
<li>Here is my execution code</li>
</ol>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="CompletableFuture&lt;xxxxResponse&gt; rpcFuture = RpcContext.getContext().asyncCall(() -&gt; invokeRpc());

rpcFuture.whenComplete((rpcResult, throwable) -&gt; {
    xxx;
});"><pre class="notranslate"><span class="pl-smi">CompletableFuture</span>&lt;<span class="pl-smi">xxxxResponse</span>&gt; <span class="pl-s1">rpcFuture</span> = <span class="pl-smi">RpcContext</span>.<span class="pl-en">getContext</span>().<span class="pl-en">asyncCall</span>(() -&gt; <span class="pl-en">invokeRpc</span>());

<span class="pl-s1">rpcFuture</span>.<span class="pl-en">whenComplete</span>((<span class="pl-s1">rpcResult</span>, <span class="pl-s1">throwable</span>) -&gt; {
    <span class="pl-s1">xxx</span>;
});</pre></div>
<ol start="2" dir="auto">
<li>
<p dir="auto">When asyncCall throw RpcException, it will return a instance of CompletableFuture, but not completed,  and so the code of the following process cannot be executed, it is blocked</p>
<p dir="auto"><a href="https://github.com/apache/dubbo/blob/master/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcContext.java#L684">RpcContext</a> asyncCall return new CompletableFuture code</p>
</li>
</ol>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/**
     * Async invocation. Timeout will be handled even if &lt;code&gt;Future.get()&lt;/code&gt; is not called.
     *
     * @param callable
     * @return get the return result from &lt;code&gt;future.get()&lt;/code&gt;
     */
    @SuppressWarnings(&quot;unchecked&quot;)
    public &lt;T&gt; CompletableFuture&lt;T&gt; asyncCall(Callable&lt;T&gt; callable) {
        try {
            hide code snippet....
        } catch (final RpcException e) {
            return new CompletableFuture&lt;T&gt;() {
                @Override
                public boolean cancel(boolean mayInterruptIfRunning) {
                    return false;
                }

                @Override
                public boolean isCancelled() {
                    return false;
                }

                @Override
                public boolean isDone() {
                    return true;
                }

                @Override
                public T get() throws InterruptedException, ExecutionException {
                    throw new ExecutionException(e.getCause());
                }

                @Override
                public T get(long timeout, TimeUnit unit)
                        throws InterruptedException, ExecutionException,
                        TimeoutException {
                    return get();
                }
            };
        }
        return ((CompletableFuture&lt;T&gt;) getContext().getFuture());
    }"><pre class="notranslate"><span class="pl-c">/**</span>
<span class="pl-c">     * Async invocation. Timeout will be handled even if &lt;code&gt;Future.get()&lt;/code&gt; is not called.</span>
<span class="pl-c">     *</span>
<span class="pl-c">     * @param callable</span>
<span class="pl-c">     * @return get the return result from &lt;code&gt;future.get()&lt;/code&gt;</span>
<span class="pl-c">     */</span>
    <span class="pl-c1">@</span><span class="pl-c1">SuppressWarnings</span>(<span class="pl-s">"unchecked"</span>)
    <span class="pl-k">public</span> &lt;<span class="pl-smi">T</span>&gt; <span class="pl-s1">CompletableFuture</span>&lt;<span class="pl-s1">T</span>&gt; <span class="pl-s1">asyncCall</span>(<span class="pl-smi">Callable</span>&lt;<span class="pl-smi">T</span>&gt; <span class="pl-s1">callable</span>) {
        <span class="pl-k">try</span> {
            <span class="pl-smi">hide</span> <span class="pl-s1">code</span> <span class="pl-s1">snippet</span>....
        } <span class="pl-k">catch</span> (<span class="pl-k">final</span> <span class="pl-smi">RpcException</span> <span class="pl-s1">e</span>) {
            <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">CompletableFuture</span>&lt;<span class="pl-smi">T</span>&gt;() {
                <span class="pl-c1">@</span><span class="pl-c1">Override</span>
                <span class="pl-k">public</span> <span class="pl-smi">boolean</span> <span class="pl-en">cancel</span>(<span class="pl-smi">boolean</span> <span class="pl-s1">mayInterruptIfRunning</span>) {
                    <span class="pl-k">return</span> <span class="pl-c1">false</span>;
                }

                <span class="pl-c1">@</span><span class="pl-c1">Override</span>
                <span class="pl-k">public</span> <span class="pl-smi">boolean</span> <span class="pl-en">isCancelled</span>() {
                    <span class="pl-k">return</span> <span class="pl-c1">false</span>;
                }

                <span class="pl-c1">@</span><span class="pl-c1">Override</span>
                <span class="pl-k">public</span> <span class="pl-smi">boolean</span> <span class="pl-en">isDone</span>() {
                    <span class="pl-k">return</span> <span class="pl-c1">true</span>;
                }

                <span class="pl-c1">@</span><span class="pl-c1">Override</span>
                <span class="pl-k">public</span> <span class="pl-smi">T</span> <span class="pl-en">get</span>() <span class="pl-k">throws</span> <span class="pl-smi">InterruptedException</span>, <span class="pl-smi">ExecutionException</span> {
                    <span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-smi">ExecutionException</span>(<span class="pl-s1">e</span>.<span class="pl-en">getCause</span>());
                }

                <span class="pl-c1">@</span><span class="pl-c1">Override</span>
                <span class="pl-k">public</span> <span class="pl-smi">T</span> <span class="pl-en">get</span>(<span class="pl-smi">long</span> <span class="pl-s1">timeout</span>, <span class="pl-smi">TimeUnit</span> <span class="pl-s1">unit</span>)
                        <span class="pl-k">throws</span> <span class="pl-smi">InterruptedException</span>, <span class="pl-smi">ExecutionException</span>,
                        <span class="pl-smi">TimeoutException</span> {
                    <span class="pl-k">return</span> <span class="pl-en">get</span>();
                }
            };
        }
        <span class="pl-k">return</span> ((<span class="pl-smi">CompletableFuture</span>&lt;<span class="pl-smi">T</span>&gt;) <span class="pl-en">getContext</span>().<span class="pl-en">getFuture</span>());
    }</pre></div>
<p dir="auto">Pls. provide [GitHub address] to reproduce this issue.</p>
<h3 dir="auto">Expected Result</h3>
<p dir="auto">Return a completed  completableFuture instance, so the code of the following process can be executed.</p>
<h3 dir="auto">Actual Result</h3>
<p dir="auto">return a not completed completableFuture instance.</p>
<p dir="auto">If there is an exception, please attach the exception trace:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Just put your stack trace here!"><pre class="notranslate"><code class="notranslate">Just put your stack trace here!
</code></pre></div>