babalae/better-genshin-impact · error · ArgumentOutOfRangeException

retryInterval 必须大于 0

Error message

retryInterval 必须大于 0

What it means

BvLocator.WithRetryInterval rejects any retryInterval value <= 0 with an ArgumentOutOfRangeException. BvLocator is the fluent locator builder in the BgiVision (BetterGI Vision) DSL; _retryInterval drives the wait between recognition retries when a locator is polled until success or timeout. A non-positive interval would produce a busy-loop or a negative delay, so the guard rejects it eagerly at build time.

Source

Thrown at BetterGenshinImpact/Core/BgiVision/BvLocator.cs:292

    {
        if (timeout <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(timeout), "timeout 必须大于 0");
        }
        _timeout = timeout;
        return this;
    }

    /// <summary>
    /// 设置重试间隔(毫秒)
    /// </summary>
    /// <param name="retryInterval">重试间隔(毫秒)</param>
    /// <returns></returns>
    public BvLocator WithRetryInterval(int retryInterval)
    {
        if (retryInterval <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(retryInterval), "retryInterval 必须大于 0");
        }
        _retryInterval = retryInterval;
        return this;
    }

    /// <summary>
    /// 为 JavaScript 提供的动态参数重载
    /// 解决 ClearScript 无法将 JS 函数隐式转换为 Action 委托的问题
    /// 支持同步和异步 JS 函数
    /// </summary>
    /// <param name="action">JS 回调函数</param>
    /// <returns></returns>
    public BvLocator WithRetryAction(dynamic action)
    {
        if (action == null)
        {
            RetryAction = null;
        }

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Pass a positive millisecond value, e.g. WithRetryInterval(200) for a 200 ms gap.
  2. If the interval comes from config, clamp it: WithRetryInterval(Math.Max(1, config.RetryInterval)).
  3. Omit the call entirely if the BvLocator default retry interval is acceptable.

Example fix

// before
var loc = page.GetByText("确认").WithRetryInterval(0);

// after
var loc = page.GetByText("确认").WithRetryInterval(200);
// or guard config-derived values
var loc = page.GetByText("确认")
    .WithRetryInterval(Math.Max(1, cfg.RetryIntervalMs));
Defensive patterns

Strategy: validation

Validate before calling

// before building the locator
int interval = sourceInterval; // from config/js
if (interval <= 0) interval = 200; // sensible default
var loc = page.GetByText("确认").WithRetryInterval(interval);

Type guard

static bool IsValidRetryInterval(int ms) => ms > 0;

Prevention

When it happens

Trigger: Calling GetByText/GetByImage(...).WithRetryInterval(0) or WithRetryInterval(-1); passing a computed/int-parsed interval whose source value is 0; a JS script invoking WithRetryInterval with a zero literal.

Common situations: Config-driven scripts that read retryInterval from a settings file and default to 0; copy-paste from WithTimeout where a 0 sentinel means 'use default' (here 0 is invalid); unit tests passing 0 expecting default behavior.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/1ce71b1fbe795c70. Report an issue: GitHub.