babalae/better-genshin-impact · error · InvalidOperationException
状态 {CurrentState} 的 Handler 返回失败
Error message
状态 {CurrentState} 的 Handler 返回失败 What it means
Thrown in RunStateMachineUntil when a registered state handler returns StateHandlerResult.Fail. Unlike Retry (transient, retried) or Wait (expected, loop continues), Fail is the handler's explicit signal of an unrecoverable error for the current state, and the state machine immediately aborts with InvalidOperationException.
Source
Thrown at BetterGenshinImpact/GameTask/Common/StateMachine/StateMachineBase.cs:762
case StateTransitionWaitStatus.IntermediateTimeout:
throw new InvalidOperationException($"状态 {CurrentState} 等待中间态转换超时");
}
break;
case StateHandlerStatus.Wait:
// 可预期的等待:状态机继续循环,重新检测状态。
Logger.LogDebug("Handler 返回 Wait,状态机继续等待");
break;
case StateHandlerStatus.Retry:
// 意外失败重试:检查重试次数。
RecordStateRetry("Handler 返回 Retry", retryPolicy, stateRetryStopwatch);
nextLoopInterval = retryInterval;
break;
case StateHandlerStatus.Fail:
// 失败:抛出异常。
throw new InvalidOperationException($"状态 {CurrentState} 的 Handler 返回失败");
}
}
else if (!EqualityComparer<TState>.Default.Equals(CurrentState, default) && _unknownStateHandler != null)
{
Logger.LogWarning("状态 {State} 无注册处理器,使用未知状态处理器", CurrentState);
await _unknownStateHandler(context);
}
else if (_unknownStateHandler != null)
{
await _unknownStateHandler(context);
}
else
{
Logger.LogWarning("状态 {State} 无注册处理器,跳过", CurrentState);
}
await Delay(nextLoopInterval, _ct);
}View on GitHub (pinned to a7cb36712d)
Solutions
- Inspect the handler for CurrentState to understand which condition produced Fail (the exception itself carries no detail — add context in the handler before returning Fail).
- If the condition is actually transient, return Retry instead so the state machine can use the retry policy.
- Fix the upstream game/UI condition that made the handler deem the state unrecoverable.
- Improve handler logging so the Fail reason is recorded before returning.
Example fix
// before — handler returns bare Fail with no recorded reason
case StateHandlerStatus.Fail:
throw new InvalidOperationException($"状态 {CurrentState} 的 Handler 返回失败");
// after — capture the reason from the handler via a richer result so the throw is diagnosable
// (handler side) return StateHandlerResult.Fail("队伍配置不存在");
// (state machine side) include the reason
throw new InvalidOperationException($"状态 {CurrentState} 的 Handler 返回失败: {result.Reason}"); Defensive patterns
Strategy: try-catch
Try / catch
try { await RunStateMachineUntil(context, targets); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Handler 返回失败"))
{ Logger.LogError(ex, "状态 {State} 处理器返回失败", CurrentState); throw; } Prevention
- Return Fail only for genuinely unrecoverable conditions; use Retry for transient ones.
- Log the specific reason inside the handler before returning Fail.
When it happens
Trigger: The handler for CurrentState executed and returned StateHandlerResult.Fail. This is by design the non-retryable failure path — e.g. the handler detected a condition that cannot be recovered (missing required element, contradictory state, fatal game error dialog).
Common situations: Handler logic intentionally returns Fail on an unrecoverable condition (e.g. an error popup appeared); a bug causes the handler to return Fail when it should return Retry; a precondition the handler assumes is violated.
Related errors
- 状态 {CurrentState} 重试超时达到上限 {retryPolicy.value} ms
- 状态 {CurrentState} 重试次数达到上限 {retryPolicy.value}
- 状态 {CurrentState} 等待中间态转换超时
- 状态机达到最大迭代次数 {maxIterations},未到达目标状态:{string.Join(", ", targe
- 未处于录制中状态,无法停止
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/47eb85edea8d3dc9.
Report an issue: GitHub.