{"record":{"id":"f2a845d50240a820","repo":"babalae/better-genshin-impact","slug":"error-f2a845","errorCode":null,"errorMessage":"材料名不能为空。","messagePattern":"材料名不能为空。","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/Common/Job/CraftMaterialTask.cs","lineNumber":162,"sourceCode":"        var rewards = await SubmitCraftAndClaimResult(adjustedQuantity);\n\n        _logger.LogInformation(\"材料 {MaterialName} 合成完成，实际设置个数：{Quantity}，产物：{Rewards}\",\n            _materialName,\n            adjustedQuantity,\n            FormatRewards(rewards));\n        return CraftMaterialResult.CreateSuccess(_materialName, _targetQuantity, adjustedQuantity, materialType, rewards);\n    }\n\n    /// <summary>\n    /// 校验任务构造参数。\n    /// </summary>\n    /// <exception cref=\"ArgumentException\">材料名为空时抛出。</exception>\n    /// <exception cref=\"ArgumentOutOfRangeException\">合成个数小于等于 0 时抛出。</exception>\n    private void ValidateArguments()\n    {\n        if (string.IsNullOrWhiteSpace(_materialName))\n        {\n            throw new ArgumentException(\"材料名不能为空。\", nameof(_materialName));\n        }\n\n        if (_targetQuantity <= 0)\n        {\n            throw new ArgumentOutOfRangeException(nameof(_targetQuantity), _targetQuantity, \"合成个数必须大于 0。\");\n        }\n    }\n\n    /// <summary>\n    /// 解析材料筛选类型，优先使用调用方显式传入的类型。\n    /// </summary>\n    /// <returns>材料筛选类型。</returns>\n    /// <exception cref=\"InvalidOperationException\">未传入材料类型且 CSV 中没有对应材料类型时抛出。</exception>\n    private string ResolveMaterialType()\n    {\n        if (!string.IsNullOrWhiteSpace(_materialType))\n        {\n            return _materialType;","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Job/CraftMaterialTask.cs#L144-L180","documentation":"Thrown as ArgumentException by CraftMaterialTask.ValidateArguments when _materialName is null, empty, or whitespace-only after trimming. The task is constructed with a material name; without one there is nothing to synthesize and the downstream CSV lookup, UI search, and OCR confirmation all depend on it.","triggerScenarios":"Constructing new CraftMaterialTask(\"\", 5) or new CraftMaterialTask(null, 5) or new CraftMaterialTask(\"   \", 5), then calling Start(ct) which calls ValidateArguments().","commonSituations":"The material name came from user config input that was left blank. A script passed an uninitialized or default string variable. The name was read from a file/database that returned an empty value.","solutions":["Check that materialName is non-empty before constructing CraftMaterialTask.","Validate user input at the UI/config layer and prompt for a required material name.","Default to a known material or abort the task if no name is provided."],"exampleFix":"// before\nvar task = new CraftMaterialTask(userInput, 10); // userInput could be \"\"\nawait task.Start(ct);\n\n// after\nif (string.IsNullOrWhiteSpace(userInput)) { /* reject early */ return; }\nvar task = new CraftMaterialTask(userInput, 10);\nawait task.Start(ct);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(materialName))\n{\n    // reject before constructing the task\n    return;\n}","typeGuard":"static bool IsValidMaterialName(string? name) => !string.IsNullOrWhiteSpace(name?.Trim());","tryCatchPattern":"try { await task.Start(ct); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"材料名不能为空\")) { /* prompt for name */ }","preventionTips":["Validate material name at the input/config layer before constructing the task.","Use a constructor guard or factory that rejects empty names early."],"tags":["validation","crafting","argument-error"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}