egametang/ET · error · RpcException

ERR_ActorLocationSenderTimeout3

ERR_ActorLocationSenderTimeout3

Error message

{requestType.FullName}

What it means

In CallInner, the actual RPC (MessageSender.Call with needException:false) to the target actor completed and returned a response. After the await, messageLocationSender was re-acquired from EntityRef and found null — the sender was disposed during the RPC round-trip to the target. The response was received but the originating sender no longer exists to process the retry logic.

Source

Thrown at Packages/cn.etetet.actorlocation/Scripts/Hotfix/Server/MessageLocationSenderComponentSystem.cs:272

                    {
                        throw new RpcException(ErrorCode.ERR_ActorLocationSenderTimeout2, $"{iRequest}");
                    }

                    messageLocationSender.ActorId = locationActorId;
                }

                if (messageLocationSender.ActorId == default)
                {
                    return MessageHelper.CreateResponse(requestType, 0, ErrorCode.ERR_NotFoundActor);
                }

                root = rootRef;
                ActorId targetActorId = messageLocationSender.ActorId;
                IResponse response = await root.GetComponent<MessageSender>().Call(targetActorId, iRequest, needException: false);
                messageLocationSender = messageLocationSenderRef;
                if (messageLocationSender == null)
                {
                    throw new RpcException(ErrorCode.ERR_ActorLocationSenderTimeout3, $"{requestType.FullName}");
                }
                
                switch (response.Error)
                {
                    case ErrorCode.ERR_NotFoundActor:
                    {
                        // 如果没找到Actor,重试
                        ++failTimes;
                        if (failTimes > 10)
                        {
                            Log.Debug($"actor send message fail, actorid: {messageLocationSender.Id} {requestType.FullName}");
                            
                            // 这里删除actor,后面等待发送的消息会判断InstanceId,InstanceId不一致返回ERR_NotFoundActor
                            self = selfRef;
                            if (self != null)
                            {
                                self.Remove(messageLocationSender.Id);
                            }

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Catch RpcException with ERR_ActorLocationSenderTimeout3.
  2. Increase MessageLocationSenderOneType.TIMEOUT_TIME if RPCs are expected to be slow.
  3. Reduce target actor response latency.
  4. Keep the sender's LastSendOrRecvTime fresh by reducing idle gaps.
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    IResponse resp = await senderOneType.Call(entityId, iLocationRequest);
}
catch (RpcException e) when (e.Error == ErrorCode.ERR_ActorLocationSenderTimeout3)
{
    // Sender disposed during the RPC round-trip — retry
    IResponse resp = await senderOneType.Call(entityId, iLocationRequest);
}

Prevention

When it happens

Trigger: Call(entityId, iLocationRequest) where the sender is disposed (Check timer, explicit Remove) during the MessageSender.Call to the target actor.

Common situations: Target actor's response takes long enough for the Check timer to expire the sender. High network latency to the target. Target actor is overloaded, widening the RPC window past TIMEOUT_TIME.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/4d17b0284f68586f. Report an issue: GitHub.