From 1be6a07d965ad439d7702d6f72fc67761943fcd9 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Tue, 1 Nov 2022 21:30:16 +0800 Subject: [PATCH] refactor: avoid NPE caused by children field data problem (#2645) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core /milestone 2.0 #### What this PR does / why we need it: 菜单和分类数列表加强健壮性,防止因为 children 字段存在垃圾数据时导致 NPE 问题 #### Which issue(s) this PR fixes: a part of #2643 #### Special notes for your reviewer: how to test it? 1. 创建一个层级结构菜单,比如 ``` A |-B |-C ``` 2. 删除菜单 C 然后访问主题端首页不会发生以下异常信息 ``` Caused by: java.lang.NullPointerException: Cannot invoke "run.halo.app.theme.finders.vo.MenuItemVo.setParentName(String)" because "childNode" is null ``` /cc @halo-dev/sig-halo #### Does this PR introduce a user-facing change? ```release-note 修复获取菜单和分类列表时会出现 NPE 的问题 ``` --- .../halo/app/theme/finders/impl/CategoryFinderImpl.java | 9 ++++++--- .../run/halo/app/theme/finders/impl/MenuFinderImpl.java | 9 ++++++--- .../app/theme/finders/impl/CategoryFinderImplTest.java | 4 +++- .../halo/app/theme/finders/impl/MenuFinderImplTest.java | 2 +- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/run/halo/app/theme/finders/impl/CategoryFinderImpl.java b/src/main/java/run/halo/app/theme/finders/impl/CategoryFinderImpl.java index 54bb219cc..ea5f16f3c 100644 --- a/src/main/java/run/halo/app/theme/finders/impl/CategoryFinderImpl.java +++ b/src/main/java/run/halo/app/theme/finders/impl/CategoryFinderImpl.java @@ -82,9 +82,12 @@ public class CategoryFinderImpl implements CategoryFinder { nameIdentityMap.forEach((name, value) -> { List children = value.getSpec().getChildren(); - if (children != null) { - for (String child : children) { - CategoryTreeVo childNode = nameIdentityMap.get(child); + if (children == null) { + return; + } + for (String child : children) { + CategoryTreeVo childNode = nameIdentityMap.get(child); + if (childNode != null) { childNode.setParentName(name); } } diff --git a/src/main/java/run/halo/app/theme/finders/impl/MenuFinderImpl.java b/src/main/java/run/halo/app/theme/finders/impl/MenuFinderImpl.java index 95e819283..2bbd9cf25 100644 --- a/src/main/java/run/halo/app/theme/finders/impl/MenuFinderImpl.java +++ b/src/main/java/run/halo/app/theme/finders/impl/MenuFinderImpl.java @@ -127,9 +127,12 @@ public class MenuFinderImpl implements MenuFinder { nameIdentityMap.forEach((name, value) -> { LinkedHashSet children = value.getSpec().getChildren(); - if (children != null) { - for (String child : children) { - MenuItemVo childNode = nameIdentityMap.get(child); + if (children == null) { + return; + } + for (String child : children) { + MenuItemVo childNode = nameIdentityMap.get(child); + if (childNode != null) { childNode.setParentName(name); } } diff --git a/src/test/java/run/halo/app/theme/finders/impl/CategoryFinderImplTest.java b/src/test/java/run/halo/app/theme/finders/impl/CategoryFinderImplTest.java index 4f862f289..b84f4b8f8 100644 --- a/src/test/java/run/halo/app/theme/finders/impl/CategoryFinderImplTest.java +++ b/src/test/java/run/halo/app/theme/finders/impl/CategoryFinderImplTest.java @@ -226,6 +226,7 @@ class CategoryFinderImplTest { } private List moreCategories() { + // see also https://github.com/halo-dev/halo/issues/2643 String s = """ [ { @@ -318,7 +319,8 @@ class CategoryFinderImplTest { "bd95f914-22fc-4de5-afcc-a9ffba2f6401", "e1150fd9-4512-453c-9186-f8de9c156c3d", "acf09686-d5a7-4227-ba8c-3aeff063f12f", - "ed064d5e-2b6f-4123-8114-78d0c6f2c4e2" + "ed064d5e-2b6f-4123-8114-78d0c6f2c4e2", + "non-existent-children-name" ] }, "status":{ diff --git a/src/test/java/run/halo/app/theme/finders/impl/MenuFinderImplTest.java b/src/test/java/run/halo/app/theme/finders/impl/MenuFinderImplTest.java index e738dc3f4..d1963434b 100644 --- a/src/test/java/run/halo/app/theme/finders/impl/MenuFinderImplTest.java +++ b/src/test/java/run/halo/app/theme/finders/impl/MenuFinderImplTest.java @@ -90,7 +90,7 @@ class MenuFinderImplTest { Menu menuX = menu("X", of("G")); Menu menuY = menu("Y", of("F")); - MenuItem itemE = menuItem("E", of("A", "C")); + MenuItem itemE = menuItem("E", of("A", "C", "non-existent-children-name")); MenuItem itemG = menuItem("G", null); MenuItem itemF = menuItem("F", of("H")); MenuItem itemA = menuItem("A", of("B"));