{"record":{"id":"74864a070845b64f","repo":"babalae/better-genshin-impact","slug":"areaname","errorCode":null,"errorMessage":"切换区域[{areaName}]失败","messagePattern":"切换区域\\[(.+?)\\]失败","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs","lineNumber":2342,"sourceCode":"            {\n                minCountry = forceCountry;\n            }\n\n            await SwitchArea(minCountry);\n            return true;\n        }\n\n        return false;\n    }\n\n    internal async Task SwitchArea(string areaName)\n    {\n        if (await TrySwitchArea(areaName))\n        {\n            return;\n        }\n\n        throw new Exception($\"切换区域[{areaName}]失败\");\n    }\n\n    private async Task<bool> TrySwitchArea(string areaName)\n    {\n        GameCaptureRegion.GameRegionClick((rect, scale) => (rect.Width - 160 * scale, rect.Height - 60 * scale));\n        var minCountryLocalized = this.stringLocalizer.WithCultureGet(this.cultureInfo, areaName);\n        var candidatesText = \"\";\n        var stopwatch = Stopwatch.StartNew();\n        while (stopwatch.ElapsedMilliseconds < SwitchAreaCandidateTimeoutMs)\n        {\n            ct.ThrowIfCancellationRequested();\n            using var ra = CaptureToRectArea();\n            var list = FindSwitchAreaCandidates(ra);\n            candidatesText = FormatSwitchAreaCandidateTexts(list);\n            var matchRect = list\n                .OrderByDescending(r => r.Y)\n                .FirstOrDefault(r => IsSwitchAreaCandidateMatch(r.Text, minCountryLocalized, areaName));\n            if (matchRect != null)","sourceCodeStart":2324,"sourceCodeEnd":2360,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs#L2324-L2360","documentation":"Thrown by SwitchArea after TrySwitchArea returns false. TrySwitchArea opens the region dropdown, OCRs candidate texts, and matches against the localized area name. If no match is found within SwitchAreaCandidateTimeoutMs, it returns false and SwitchArea throws this generic Exception.","triggerScenarios":"Called from SwitchArea(areaName). TrySwitchArea's while-loop expires (SwitchAreaCandidateTimeoutMs) without finding a candidate whose text matches the localized area name via IsSwitchAreaCandidateMatch.","commonSituations":"The area name is misspelled or not a valid region in the current map; OCR fails to read the dropdown text due to font/rendering differences; the region dropdown didn't open or is in a different state; game language doesn't match the expected localized names; UI scaling distorts the OCR region.","solutions":["Verify areaName is a valid region name for the current map (e.g. '蒙德', '璃月').","Check the game language setting matches the expected localization.","Increase SwitchAreaCandidateTimeoutMs if the UI is slow.","Inspect the logged OCR candidate texts to diagnose OCR failures.","Ensure the region dropdown is properly opened before the OCR scan."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    await task.SwitchArea(areaName);\n}\ncatch (Exception ex) when (ex.Message.StartsWith(\"切换区域\"))\n{\n    Logger.LogWarning($\"Area switch failed for {areaName}. Check OCR logs for candidate texts.\");\n    throw;\n}","preventionTips":["Verify areaName is a valid region for the current map.","Ensure the game language matches the expected localized names.","Inspect the logged OCR candidate texts to diagnose OCR failures.","Increase SwitchAreaCandidateTimeoutMs if the UI is slow to render."],"tags":["map-navigation","area-switch","ocr","timeout"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}