egametang/ET · error · RpcException
Rpc error: actorId: {actorId} {request}, response: {response
Error message
Rpc error: actorId: {actorId} {request}, response: {response} What it means
A generic RPC failure: the response carried a non-zero error code that ErrorCode.IsRpcNeedThrowException considers fatal, and needException was true (the default). Unlike the timeout case (241) this covers all other serious RPC error codes — the response came back but reported an error the framework treats as unrecoverable. The message includes the actorId, request, and response for diagnosis.
Source
Thrown at Packages/cn.etetet.netinner/Scripts/Hotfix/Server/MessageSenderSystem.cs:72
{
// 发给NetInner纤程
A2NetInner_Request a2NetInner_Request = A2NetInner_Request.Create();
a2NetInner_Request.ActorId = actorId;
a2NetInner_Request.MessageObject = request;
FiberInstanceId netInnerFiberInstanceId = self.GetSingleton<ProcessFiberAddressSingleton>().Get(SceneType.NetInner);
using A2NetInner_Response a2NetInnerResponse = await self.ProcessInnerSender.Call(
netInnerFiberInstanceId, a2NetInner_Request, timeout) as A2NetInner_Response;
response = a2NetInnerResponse.MessageObject;
}
if (response.Error == ErrorCode.ERR_MessageTimeout)
{
throw new RpcException(response.Error, $"Rpc error: request, 注意Actor消息超时,请注意查看是否死锁或者没有reply: actorId: {actorId} {request}, response: {response}");
}
if (needException && ErrorCode.IsRpcNeedThrowException(response.Error))
{
throw new RpcException(response.Error, $"Rpc error: actorId: {actorId} {request}, response: {response}");
}
return response;
}
}
}
View on GitHub (pinned to 5cab01f7a8)
Solutions
- Inspect response.Error in the exception message to identify the specific error code, then look up its meaning in ErrorCode.
- If the failure is an expected/optional outcome, pass needException: false and check response.Error yourself.
- Fix the remote handler that is producing the error code (check its logs for the original exception).
- Verify request/response message definitions match between caller and handler assemblies (no stale generated code).
Example fix
// before — default throws on any serious error
var resp = await MessageSender.Instance.Call(actorId, request);
// after — tolerate expected errors for optional lookups
var resp = await MessageSender.Instance.Call(actorId, request, needException: false);
if (resp.Error != ErrorCode.ERR_OK)
{
// handle gracefully
return default;
} Defensive patterns
Strategy: try-catch
Try / catch
var resp = await sender.Call(actorId, request, needException: false);
if (resp.Error != ErrorCode.ERR_OK) { /* handle expected failure */ } Prevention
- Pass needException: false for calls where failure is an expected outcome.
- Always inspect response.Error and map known codes to user-facing behavior.
- Keep request/response message definitions in sync across assemblies.
When it happens
Trigger: The remote handler explicitly set a non-zero error on the response (e.g. entity not found, permission denied, internal error); the inner transport returned a transport-level error code; the target fiber threw an exception that was serialized into the response error code.
Common situations: Calling a scene/fiber whose handler logic returns an error for the given input (invalid id, missing config); version mismatch where the request/response contract changed; the caller passed needException=true (default) for a call that is expected to fail occasionally and should have used needException=false.
Related errors
- actor id is 0: {request}
- Rpc error: request, 注意Actor消息超时,请注意查看是否死锁或者没有reply: actorId:
- actor id is 0: {message}
- actor id is 0: {iRequest}
- Rpc error: {request}, response: {response}
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/487d6340a345ef86.
Report an issue: GitHub.