{"record":{"id":"97bc1e02f6905a12","repo":"YunaiV/ruoyi-vue-pro","slug":"areautils","errorCode":null,"errorMessage":"AreaUtils 初始化失败","messagePattern":"AreaUtils 初始化失败","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java","lineNumber":67,"sourceCode":"            // 从 csv 中加载数据\n            List<CsvRow> rows = CsvUtil.getReader().read(ResourceUtil.getUtf8Reader(\"area.csv\")).getRows();\n            rows.remove(0); // 删除 header\n            for (CsvRow row : rows) {\n                Area area = new Area(Integer.valueOf(row.get(0)), row.get(1), Integer.valueOf(row.get(2)), null, new ArrayList<>());\n                areas.put(area.getId(), area);\n            }\n\n            // 构建父子关系：因为 Area 中没有 parentId 字段,所以需要重复读取\n            for (CsvRow row : rows) {\n                Area area = areas.get(Integer.valueOf(row.get(0))); // 自己\n                Area parent = areas.get(Integer.valueOf(row.get(3))); // 父\n                Assert.isTrue(area != parent, \"{}:父子节点相同\", area.getName());\n                area.setParent(parent);\n                parent.getChildren().add(area);\n            }\n            log.info(\"启动加载 AreaUtils 成功，耗时 ({}) 毫秒\", System.currentTimeMillis() - now);\n        } catch (Exception e) {\n            throw new RuntimeException(\"AreaUtils 初始化失败\", e);\n        }\n    }\n\n    /**\n     * 获得指定编号对应的区域\n     *\n     * @param id 区域编号\n     * @return 区域\n     */\n    public static Area getArea(Integer id) {\n        return areas.get(id);\n    }\n\n    /**\n     * 获得指定区域对应的编号\n     *\n     * @param pathStr 区域路径，例如说：河南省/石家庄市/新华区\n     * @return 区域","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/YunaiV/ruoyi-vue-pro/blob/0418084e222612af2fc1141f566af454f9236ab1/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java#L49-L85","documentation":"AreaUtils is a static initializer that parses a CSV of Chinese administrative areas (area.csv), builds parent/child relationships, and fails fast with RuntimeException('AreaUtils 初始化失败') on any parse/assertion/IO error. The assert area != parent and parent null-deref are the most common sub-failures.","triggerScenarios":"The bundled area.csv is missing from the classpath (shaded jar stripped it); a malformed CSV row (non-numeric id, missing parent column, a row whose id equals its parentId); duplicate ids; ResourceUtil.readFileAsString returns null.","commonSituations":"Building a fat/shaded jar that excludes the csv resource; upgrading the data-permission/ip module with a CSV format change; custom CSV with malformed rows.","solutions":["Inspect the caused-by exception: IOException -> missing/malformed resource; IllegalArgumentException -> assert area!=parent or duplicate id.","Ensure area.csv is on the classpath (check the packaged jar).","Fix the offending CSV row (ensure parentId differs from id and exists in the map)."],"exampleFix":"// before: row where id == parentId triggers Assert\n// area.csv: 110000,北京市, ..., 110000\n// after: set parent to the real parent id\n// area.csv: 110000,北京市, ..., 100000","handlingStrategy":"try-catch","validationCode":"if (getClass().getClassLoader().getResource(\"area.csv\") == null)\n    throw new IllegalStateException(\"area.csv missing from classpath\");","typeGuard":"null","tryCatchPattern":"try { AreaUtils.getArea(id); }\ncatch (RuntimeException e) { if (e.getMessage().contains(\"AreaUtils\")) { /* disable area features */ } throw e; }","preventionTips":["Ensure area.csv is packaged (check the jar)","Validate CSV rows: id != parentId, parent exists","Exclude CSV from resource filtering"],"tags":["yudao","ip","startup","resource-loading"],"backgroundTag":null,"analyzedSha":"0418084e222612af2fc1141f566af454f9236ab1","analyzedAt":"2026-08-14T00:56:18.412Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}