{"record":{"id":"f1c9e6a552d83ca2","repo":"egametang/ET","slug":"service-discovery-proxy-service-call-error-request","errorCode":null,"errorMessage":"service discovery proxy service call error request: {requestName} sceneType: {sceneTypeName} error: {error} message: {message}","messagePattern":"service discovery proxy service call error request: (.+?) sceneType: (.+?) error: (.+?) message: (.+?)","errorType":"exception","errorClass":"RpcException","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.servicediscovery/Scripts/Hotfix/Server/ServiceDiscoveryProxySystem.cs","lineNumber":379,"sourceCode":"                        throw new Exception(\n                            $\"service discovery proxy service response type mismatch request: {requestName}, actual: {rawResponse?.GetType().Name}\");\n                    }\n\n                    if (ShouldRetryServiceCallError(response.Error))\n                    {\n                        int error = response.Error;\n                        string message = response.Message;\n                        (response as MessageObject)?.Dispose();\n                        throw new RpcException(error,\n                            $\"service discovery proxy retryable service call error request: {requestName} sceneType: {sceneTypeName} error: {error} message: {message}\");\n                    }\n\n                    if (throwResponseError && response.Error != ErrorCode.ERR_Success)\n                    {\n                        int error = response.Error;\n                        string message = response.Message;\n                        (response as MessageObject)?.Dispose();\n                        throw new RpcException(error,\n                            $\"service discovery proxy service call error request: {requestName} sceneType: {sceneTypeName} error: {error} message: {message}\");\n                    }\n\n                    return response;\n                }\n                catch (RpcException rpcException)\n                {\n                    ++retryCount;\n                    self = selfRef;\n                    if (self == null)\n                    {\n                        throw new Exception(\"service discovery proxy disposed\");\n                    }\n\n                    if (!ShouldRetryServiceCallError(rpcException.Error) || retryCount >= self.ServiceResolveRetryTimes)\n                    {\n                        throw;\n                    }","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.servicediscovery/Scripts/Hotfix/Server/ServiceDiscoveryProxySystem.cs#L361-L397","documentation":"RpcException thrown at line 379 in CallBySceneTypeAsync on the throwResponseError=true path: the target service returned Error != ERR_Success, but unlike 337 the error is NOT retryable (or the caller explicitly opted into throwing all non-success responses). The response is disposed and the error code/message wrapped and thrown to the caller. This is the explicit 'surface the service's business error' failure.","triggerScenarios":"CallBySceneTypeAsync is called with throwResponseError=true and the resolved service returns a non-success, non-retryable error code (an application/business error). The proxy does not retry and propagates it immediately.","commonSituations":"The target service rejected the request for a business reason (not found, invalid state, permission); the caller chose throwResponseError=true to get exceptions instead of inspecting response.Error; a non-failover error code that the proxy will not retry.","solutions":["Handle the RpcException at the call site per the target service's contract (it is an application error, not infrastructure).","If the error is unexpected, inspect its code/message to map it to the target service's failure modes.","Only set throwResponseError=true when the caller is prepared to catch and interpret business errors."],"exampleFix":"// before\nvar resp = await proxy.CallBySceneTypeAsync<T>(sceneType, req, name, throwResponseError: true);\n\n// after: handle the business error explicitly\ncatch (RpcException e)\n{\n    Log.Warning($\"service {name} returned business error {e.Error}: {e.Message}\");\n    // map e.Error to a caller-facing result\n}","handlingStrategy":"try-catch","validationCode":"// Only request thrown errors when you intend to handle business errors.\nbool throwResponseError = callerCanHandleBusinessError;","typeGuard":null,"tryCatchPattern":"catch (RpcException e)\n{\n    // business/application error from the target service (non-retryable)\n    Log.Warning($\"service {name} business error {e.Error}: {e.Message}\");\n    // map e.Error to a caller-facing result\n}","preventionTips":["Only set throwResponseError=true when ready to interpret business errors.","Map known target error codes to caller-facing outcomes.","Inspect response.Error instead of throwing when you want to branch on errors."],"tags":["csharp","et-framework","service-discovery","rpc","proxy","error-handling","business-logic"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}