babalae/better-genshin-impact · error · ArgumentException

javaScript不能为空

Error message

javaScript不能为空

What it means

Thrown at the top of Salvage5Star when this.javaScript is null. Salvage5Star is only meant to run when a custom JS filter is configured; the null-check with ArgumentException signals a contract violation by the caller. Start() guards the call with 'if (javaScript != null)' so reaching this throw means state was mutated or Start's logic was bypassed.

Source

Thrown at BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTask.cs:377

            // 逐一点选查看面板筛选
            await Salvage5Star();
            logger.LogInformation("筛选完毕,请复查并手动分解");
        }
        else
        {
            input.Keyboard.KeyPress(User32.VK.VK_ESCAPE);

            if (returnToMainUi)
            {
                await new ReturnMainUiTask().Start(ct);
            }
        }
    }

    private async Task Salvage5Star()
    {
        string javaScript = this.javaScript ?? throw new ArgumentException($"{nameof(this.javaScript)}不能为空");
        int count = this.maxNumToCheck ?? throw new ArgumentException($"{nameof(this.maxNumToCheck)}不能为空");
        RecognitionFailurePolicy recognitionFailurePolicy = this.recognitionFailurePolicy ?? throw new ArgumentException($"{nameof(this.recognitionFailurePolicy)}不能为空");

        GridParams gridParams = GridParams.Templates[GridScreenName.ArtifactSalvage];
        GridScreen gridScreen = new GridScreen(gridParams, this.logger, this.ct); // 圣遗物分解Grid有4行9列
        gridScreen.OnAfterTurnToNewPage += GridScreen.DrawItemsAfterTurnToNewPage;
        gridScreen.OnBeforeScroll += () => VisionContext.Instance().DrawContent.ClearAll();
        try
        {
            await foreach ((ImageRegion pageRegion, Rect itemRect) in gridScreen)
            {
                using ImageRegion itemRegion = pageRegion.DeriveCrop(itemRect);
                Rect gridRect = itemRegion.ToRect();
                if (GetArtifactStatus(itemRegion.SrcMat) == ArtifactStatus.None)
                {
                    itemRegion.Click();
                    await Delay(300, ct);

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Ensure AutoArtifactSalvageTaskParam.JavaScript is set when 5-star JS filtering is desired.
  2. Keep Start's 'if (javaScript != null)' guard intact so Salvage5Star is unreachable without JS.
  3. Validate the param in the constructor and throw a clearer configuration error there.
  4. If JS-less salvage is intended, do not call Salvage5Star.

Example fix

// before
// caller built param with JavaScript = null, then Start reached Salvage5Star
// after - guard in constructor
public AutoArtifactSalvageTask(AutoArtifactSalvageTaskParam param, ILogger? logger = null)
{
    ...
    if (string.IsNullOrWhiteSpace(param.JavaScript))
        throw new ArgumentException("5星分解需要配置 JavaScript 过滤脚本", nameof(param));
    this.javaScript = param.JavaScript;
}
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(param.JavaScript))
    throw new ArgumentException("5星 JS 过滤脚本未配置", nameof(param.JavaScript));

Prevention

When it happens

Trigger: Calling Salvage5Star directly with a param object whose JavaScript field is null/empty; Start's 'if (javaScript != null)' guard was removed or short-circuited; AutoArtifactSalvageTaskParam constructed without JavaScript but Salvage5Star invoked anyway.

Common situations: User configured only star-based quick-salvage (no JS filter) yet code path entered Salvage5Star; param deserialization left JavaScript null; refactor broke the null guard in Start.

Related errors


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