{"record":{"id":"881aa64a411d4bd4","repo":"babalae/better-genshin-impact","slug":"error-881aa6","errorCode":null,"errorMessage":"合成提交与确认流程失败。","messagePattern":"合成提交与确认流程失败。","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/Common/Job/CraftMaterialTask.cs","lineNumber":560,"sourceCode":"    private async Task<List<RewardItem>> SubmitCraftAndClaimResult(int actualQuantity)\n    {\n        try\n        {\n            var rewards = CreateDefaultCraftRewards(actualQuantity);\n\n            // 分别是右下角合成按钮、弹窗确认合成按钮、弹窗产物确认按钮。\n            await Page.GetByText(\"合成\", Rect1080(1588, 967, 332, 113)).Click(5000);\n            await Page.GetByText(\"确认\", Rect1080(980, 725, 370, 70)).Click(5000);\n\n            var resultConfirmButtons = await Page.GetByText(\"确认\", Rect1080(790, 875, 340, 65)).WaitFor(5000);\n            rewards = RecognizeCraftRewards(actualQuantity);\n\n            resultConfirmButtons.First().Click();\n            return rewards;\n        }\n        catch (TimeoutException e)\n        {\n            throw new InvalidOperationException(\"合成提交与确认流程失败。\", e);\n        }\n    }\n\n    /// <summary>\n    /// 识别产物弹窗中的实际合成产物，失败时回退为默认产物。\n    /// </summary>\n    /// <param name=\"actualQuantity\">实际合成个数。</param>\n    /// <returns>识别到的产物汇总。</returns>\n    private List<RewardItem> RecognizeCraftRewards(int actualQuantity)\n    {\n        try\n        {\n            var rewardSummary = RewardResultRecognizer.Instance.RecognizeMultiPage(1);\n            var rewards = rewardSummary\n                .Where(pair => pair.Value > 0)\n                .Select((pair, index) => new RewardItem(pair.Key, -1, pair.Value, index))\n                .ToList();\n","sourceCodeStart":542,"sourceCodeEnd":578,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Job/CraftMaterialTask.cs#L542-L578","documentation":"Thrown by SubmitCraftAndClaimResult when any of the three sequential UI clicks (合成 button, 确认 confirm, result 确认) times out. The inner TimeoutException comes from Page.GetByText(...).Click(5000) / WaitFor(5000) — a 5-second wait for the localized text within a bounded rect.","triggerScenarios":"Page.GetByText(\"合成\", Rect1080(1588,967,332,113)).Click(5000) or one of the two 确认 waits throws TimeoutException because the text element was not found inside its rect within 5000ms. Triggered when the craft panel never opened, a confirm popup did not appear, or the text is in a different language/position.","commonSituations":"Game language does not match the expected localized strings (合成/确认); the prior SetCraftQuantity left the UI in an unexpected state so the 合成 button is absent; a popup (e.g. resin-full, material-short) blocked the confirm; capture lag exceeded 5s.","solutions":["Confirm the game language matches the localized strings used by GetByText.","Increase the 5000ms timeout or retry the whole submit sequence once.","Before clicking 合成, assert the craft panel is in the expected state and dismiss unexpected popups.","Log which of the three steps threw (wrap each Click separately) to localize the failure."],"exampleFix":"// before\ntry\n{\n    await Page.GetByText(\"合成\", Rect1080(1588, 967, 332, 113)).Click(5000);\n    await Page.GetByText(\"确认\", Rect1080(980, 725, 370, 70)).Click(5000);\n    var resultConfirmButtons = await Page.GetByText(\"确认\", Rect1080(790, 875, 340, 65)).WaitFor(5000);\n    ...\n}\ncatch (TimeoutException e)\n{\n    throw new InvalidOperationException(\"合成提交与确认流程失败。\", e);\n}\n\n// after: identify the failing step and retry once\ncatch (TimeoutException e)\n{\n    Logger.LogError(\"合成确认流程超时：{Step}\", e.Message);\n    throw new InvalidOperationException($\"合成提交与确认流程失败（{e.Message}）。\", e);\n}","handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"try { return await SubmitCraftAndClaimResult(qty); }\ncatch (InvalidOperationException e) when (e.InnerException is TimeoutException)\n{ /* dismiss unexpected popups, then retry the submit sequence once */ }","preventionTips":["Match the GetByText strings to the configured game language.","Wrap each of the three clicks separately so logs name the failing step.","Dismiss resin-full / announcement popups before starting the submit sequence."],"tags":["ui-automation","crafting","timeout","localization"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}