{"record":{"id":"e7e527dd6f5bc63e","repo":"apache/dubbo","slug":"mock-error-mt-getmessage-invoke-error-is","errorCode":null,"errorMessage":"mock error : {mt.getMessage()}, invoke error is :{StringUtils.toString(t)}","messagePattern":"mock error : (.+?), invoke error is :(.+?)","errorType":"exception","errorClass":"RpcException","httpStatus":null,"severity":"error","filePath":"dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvoker.java","lineNumber":174,"sourceCode":"        Result result;\n        Invoker<T> mockInvoker;\n\n        RpcInvocation rpcInvocation = (RpcInvocation) invocation;\n        rpcInvocation.setInvokeMode(RpcUtils.getInvokeMode(getUrl(), invocation));\n\n        List<Invoker<T>> mockInvokers = selectMockInvoker(invocation);\n        if (CollectionUtils.isEmpty(mockInvokers)) {\n            mockInvoker = (Invoker<T>) new MockInvoker(getUrl(), directory.getInterface());\n        } else {\n            mockInvoker = mockInvokers.get(0);\n        }\n        try {\n            result = mockInvoker.invoke(invocation);\n        } catch (RpcException mockException) {\n            if (mockException.isBiz()) {\n                result = AsyncRpcResult.newDefaultAsyncResult(mockException.getCause(), invocation);\n            } else {\n                throw new RpcException(\n                        mockException.getCode(), getMockExceptionMessage(e, mockException), mockException.getCause());\n            }\n        } catch (Throwable me) {\n            throw new RpcException(getMockExceptionMessage(e, me), me.getCause());\n        }\n        if (setFutureWhenSync || rpcInvocation.getInvokeMode() != InvokeMode.SYNC) {\n            // set server context\n            RpcContext.getServiceContext()\n                    .setFuture(new FutureAdapter<>(((AsyncRpcResult) result).getResponseFuture()));\n        }\n        return result;\n    }\n\n    private String getMockExceptionMessage(Throwable t, Throwable mt) {\n        String msg = \"mock error : \" + mt.getMessage();\n        if (t != null) {\n            msg = msg + \", invoke error is :\" + StringUtils.toString(t);\n        }","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvoker.java#L156-L192","documentation":"Thrown by MockClusterInvoker.doMockInvoke when the mock invocation itself fails with a non-business RpcException (mockException.isBiz() is false). The original real-invocation error (passed in as 'e') is appended via getMockExceptionMessage so both the mock failure and the triggering failure are visible. This means fail-mock fallback was attempted but the mock path also failed at the transport/cluster layer.","triggerScenarios":"A service call fails (network/no-provider/timeout) triggering mock fallback (mock= configured), and the mock invocation then also throws a non-biz RpcException, e.g. the mock returns force vs default, mock URL malformed, or the MockInvoker cannot resolve/execute the mock implementation. The re-thrown RpcException carries the mock's code and the combined message.","commonSituations":"Configuring mock=\"force:return ...\" or mock=\"throw ...\" with a malformed mock spec; mock implementation class missing on classpath; the mock targets a non-existent method; the original failure was no-provider and the mock invoker itself cannot be constructed (selectMockInvoker empty + MockInvoker init fails).","solutions":["Validate the mock configuration syntax: mock=\"return VALUE\", mock=\"throw\", mock=\"force:return VALUE\", or a fully-qualified MockImpl class name that exists.","Ensure the mock implementation class (if specified) is on the classpath and implements the service interface.","Distinguish the two errors in the message: fix the underlying real-invocation error (first cause) since the mock only ran because the real call already failed.","Use mock=\"force:return\" during tests to isolate whether the mock path itself is broken independent of provider state."],"exampleFix":"// before: malformed mock spec causes mock fallback to fail too\n<dubbo:reference interface=\"com.acme.Svc\" mock=\"return {\\\"ok\\\":true\"/>\n\n// after: valid JSON + force to test the mock path in isolation\n<dubbo:reference interface=\"com.acme.Svc\" mock=\"force:return {&quot;ok&quot;:true}\"/>","handlingStrategy":"try-catch","validationCode":"// Validate the mock spec syntax before the call\nString mock = url.getParameter(\"mock\");\nif (mock != null && !(mock.startsWith(\"return\") || mock.startsWith(\"force:return\")\n        || mock.startsWith(\"throw\") || isValidFqcn(mock))) {\n    throw new IllegalStateException(\"malformed mock spec: \" + mock);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return service.call(req);\n} catch (RpcException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"mock error :\")) {\n        // both real call and mock failed; inspect combined message + cause\n        log.error(\"fail-mock fallback also failed\", e);\n    }\n    throw e;\n}","preventionTips":["Use the documented mock spec forms (return/force:return/throw/FQCN).","Keep mock implementations on the classpath and interface-conformant.","Test the mock path in isolation with mock=\"force:return\"."],"tags":["cluster","mock","fail-mock","fallback","config"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}