refactor: avoid NPE caused by children field data problem (#2645)

#### 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 的问题
```
pull/2652/head^2
guqing 2022-11-01 21:30:16 +08:00 committed by GitHub
parent c3a3281fcc
commit 1be6a07d96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 8 deletions

View File

@ -82,9 +82,12 @@ public class CategoryFinderImpl implements CategoryFinder {
nameIdentityMap.forEach((name, value) -> { nameIdentityMap.forEach((name, value) -> {
List<String> children = value.getSpec().getChildren(); List<String> children = value.getSpec().getChildren();
if (children != null) { if (children == null) {
for (String child : children) { return;
CategoryTreeVo childNode = nameIdentityMap.get(child); }
for (String child : children) {
CategoryTreeVo childNode = nameIdentityMap.get(child);
if (childNode != null) {
childNode.setParentName(name); childNode.setParentName(name);
} }
} }

View File

@ -127,9 +127,12 @@ public class MenuFinderImpl implements MenuFinder {
nameIdentityMap.forEach((name, value) -> { nameIdentityMap.forEach((name, value) -> {
LinkedHashSet<String> children = value.getSpec().getChildren(); LinkedHashSet<String> children = value.getSpec().getChildren();
if (children != null) { if (children == null) {
for (String child : children) { return;
MenuItemVo childNode = nameIdentityMap.get(child); }
for (String child : children) {
MenuItemVo childNode = nameIdentityMap.get(child);
if (childNode != null) {
childNode.setParentName(name); childNode.setParentName(name);
} }
} }

View File

@ -226,6 +226,7 @@ class CategoryFinderImplTest {
} }
private List<Category> moreCategories() { private List<Category> moreCategories() {
// see also https://github.com/halo-dev/halo/issues/2643
String s = """ String s = """
[ [
{ {
@ -318,7 +319,8 @@ class CategoryFinderImplTest {
"bd95f914-22fc-4de5-afcc-a9ffba2f6401", "bd95f914-22fc-4de5-afcc-a9ffba2f6401",
"e1150fd9-4512-453c-9186-f8de9c156c3d", "e1150fd9-4512-453c-9186-f8de9c156c3d",
"acf09686-d5a7-4227-ba8c-3aeff063f12f", "acf09686-d5a7-4227-ba8c-3aeff063f12f",
"ed064d5e-2b6f-4123-8114-78d0c6f2c4e2" "ed064d5e-2b6f-4123-8114-78d0c6f2c4e2",
"non-existent-children-name"
] ]
}, },
"status":{ "status":{

View File

@ -90,7 +90,7 @@ class MenuFinderImplTest {
Menu menuX = menu("X", of("G")); Menu menuX = menu("X", of("G"));
Menu menuY = menu("Y", of("F")); 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 itemG = menuItem("G", null);
MenuItem itemF = menuItem("F", of("H")); MenuItem itemF = menuItem("F", of("H"));
MenuItem itemA = menuItem("A", of("B")); MenuItem itemA = menuItem("A", of("B"));