{"record":{"id":"c7173fd48c9340fb","repo":"babalae/better-genshin-impact","slug":"layerid","errorCode":null,"errorMessage":"彩色分层地图 {LayerId} 读取失败","messagePattern":"彩色分层地图 (.+?) 读取失败","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"BetterGenshinImpact/GameTask/Common/Map/Maps/Base/BaseMapLayerByTemplateMatch.cs","lineNumber":37,"sourceCode":"    public string LayerGroupId { get; set; } = string.Empty;\n    public string LayerId { get; set; } = string.Empty;\n    public string Name { get; set; } = string.Empty;\n    public float Scale { get; set; } = 1;\n    public int Floor { get; set; } = 0;\n    public float Top { get; set; } = 0;\n    public float Left { get; set; } = 0;\n    public bool IsOverSize  { get; set; } = false;\n    [JsonIgnore]\n    public required FastSqDiffMatcher CoarseColorMatcher; // 小尺寸彩图\n    [JsonIgnore]\n    public Mat FineGrayMap = new Mat(); // 大尺寸灰度图\n    \n    public void LoadLayer(string layerDir)\n    {\n        SpeedTimer speedTimer = new($\"加载 {LayerId} 地图图片\");\n        var colorMapFileName = LayerId + \"_color\" + \".webp\";\n        var colorMapPath = Path.Combine(layerDir, colorMapFileName);\n        var coarseColorMap = Bv.ImRead(colorMapPath)?? throw new Exception($\"彩色分层地图 {LayerId} 读取失败\");\n        speedTimer.Record(\"精确匹配用彩图\");\n        CoarseColorMatcher = new FastSqDiffMatcher(coarseColorMap, new Size(52, 52));\n        var grayMapFileName = LayerId + \"_gray\" + (IsOverSize ? \".png\" : \".webp\");\n        var grayMapPath = Path.Combine(layerDir, grayMapFileName);\n        FineGrayMap = Bv.ImRead(grayMapPath, ImreadModes.Grayscale)?? throw new Exception($\"灰度分层地图 {LayerId} 读取失败\");\n        speedTimer.Record(\"粗匹配用灰度图\");\n        speedTimer.DebugPrint();\n    }\n\n    public static List<BaseMapLayerByTemplateMatch> LoadLayers(SceneBaseMapByTemplateMatch sceneBaseMap)\n    {\n        var layers = new List<BaseMapLayerByTemplateMatch>();\n        var layerDir = Path.Combine(Global.Absolute(@\"Assets\\Map\\\"), sceneBaseMap.Type.ToString());\n        if (!Directory.Exists(layerDir))\n        {\n            return layers;\n        }\n        var jsonFiles = Directory.GetFiles(layerDir, \"*.json\", SearchOption.AllDirectories);","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Map/Maps/Base/BaseMapLayerByTemplateMatch.cs#L19-L55","documentation":"Thrown in BaseMapLayerByTemplateMatch.LoadLayer when reading the color map image for a template-match layer. NOTE: Bv.ImRead returns a non-nullable Mat (it calls Mat.FromStream(File.OpenRead(fileName), flags)), so the '?? throw' is effectively dead code — ImRead can never return null. The real failure path is File.OpenRead throwing FileNotFoundException/FolderNameException when colorMapPath (LayerId + \"_color.webp\") does not exist. The custom message is therefore only reachable in theory, not in practice.","triggerScenarios":"LoadLayer computes colorMapPath = Path.Combine(layerDir, LayerId + \"_color.webp\") and calls Bv.ImRead(colorMapPath). If the .webp is missing, File.OpenRead throws FileNotFoundException (not this exception). The '?? throw' branch is unreachable because ImRead's declared return type is non-nullable Mat.","commonSituations":"A template-match layer JSON was deserialized (LayerId set) but its corresponding <LayerId>_color.webp was not shipped in Assets\\Map\\<Type>; LayerId in the JSON doesn't match the image filename; assets partially deployed.","solutions":["Verify that <LayerId>_color.webp exists in the map directory for every layer defined in the JSON files.","Make sure the LayerId in each JSON matches the image filename prefix exactly.","If you actually want a clear error, guard with File.Exists before ImRead, since the current ?? never fires.","Redeploy the complete map image assets for the affected map type."],"exampleFix":"// before\nvar coarseColorMap = Bv.ImRead(colorMapPath)?? throw new Exception($\"彩色分层地图 {LayerId} 读取失败\");\n\n// after — ImRead is non-nullable, so guard existence explicitly to get the intended message\nif (!File.Exists(colorMapPath)) throw new Exception($\"彩色分层地图 {LayerId} 读取失败: 缺少 {colorMapPath}\");\nvar coarseColorMap = Bv.ImRead(colorMapPath);","handlingStrategy":"validation","validationCode":"var colorMapPath = Path.Combine(layerDir, LayerId + \"_color.webp\");\nif (!File.Exists(colorMapPath)) throw new FileNotFoundException($\"缺少彩色地图: {colorMapPath}\", colorMapPath);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ship <LayerId>_color.webp for every layer defined in JSON.","Keep LayerId in JSON identical to the image filename prefix.","Note Bv.ImRead is non-nullable — guard with File.Exists to get a meaningful error."],"tags":["map-data","asset-loading","missing-file","template-match","dead-code"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}