Skip to content

Commit ed0058a

Browse files
Fix PanicException: failed to get child with id= after updating content types (#17702)
* Remove tree node from hierarchy after clearing branch * Refactor ClearBranchLocked to split clearing child and siblings
1 parent b0aed39 commit ed0058a

File tree

1 file changed

+36
-35
lines changed

1 file changed

+36
-35
lines changed

src/Umbraco.PublishedCache.NuCache/ContentStore.cs

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,48 +1276,42 @@ public bool ClearLocked(int id)
12761276

12771277
// try to find the content
12781278
// if it is not there, nothing to do
1279-
_contentNodes.TryGetValue(id, out LinkedNode<ContentNode?>? link); // else null
1280-
if (link?.Value == null)
1279+
if (_contentNodes.TryGetValue(id, out LinkedNode<ContentNode?>? link) &&
1280+
link.Value is ContentNode content)
12811281
{
1282-
return false;
1283-
}
1282+
if (_logger.IsEnabled(LogLevel.Debug))
1283+
{
1284+
_logger.LogDebug("Clear content ID: {ContentId}", content.Id);
1285+
}
12841286

1285-
ContentNode? content = link.Value;
1287+
// clear the entire branch
1288+
ClearBranchLocked(content);
12861289

1287-
if (_logger.IsEnabled(LogLevel.Debug))
1288-
{
1289-
_logger.LogDebug("Clear content ID: {ContentId}", content.Id);
1290-
}
1291-
1292-
// clear the entire branch
1293-
ClearBranchLocked(content);
1290+
// manage the tree
1291+
RemoveTreeNodeLocked(content);
12941292

1295-
// manage the tree
1296-
RemoveTreeNodeLocked(content);
1293+
return true;
1294+
}
12971295

1298-
return true;
1296+
return false;
12991297
}
13001298

13011299
private void ClearBranchLocked(int id)
13021300
{
1303-
_contentNodes.TryGetValue(id, out LinkedNode<ContentNode?>? link);
1304-
if (link?.Value == null)
1301+
if (_contentNodes.TryGetValue(id, out LinkedNode<ContentNode?>? link) &&
1302+
link.Value is ContentNode content)
13051303
{
1306-
return;
1307-
}
1304+
// clear the entire branch
1305+
ClearBranchLocked(content);
13081306

1309-
ClearBranchLocked(link.Value);
1307+
// manage the tree
1308+
RemoveTreeNodeLocked(content);
1309+
}
13101310
}
13111311

1312-
private void ClearBranchLocked(ContentNode? content)
1312+
private void ClearBranchLocked(ContentNode content)
13131313
{
1314-
// This should never be null, all code that calls this method is null checking but we've seen
1315-
// issues of null ref exceptions in issue reports so we'll double check here
1316-
if (content == null)
1317-
{
1318-
throw new ArgumentNullException(nameof(content));
1319-
}
1320-
1314+
// Clear content node
13211315
SetValueLocked(_contentNodes, content.Id, null);
13221316
if (_localDb != null)
13231317
{
@@ -1326,14 +1320,21 @@ private void ClearBranchLocked(ContentNode? content)
13261320

13271321
_contentKeyToIdMap.TryRemove(content.Uid, out _);
13281322

1329-
var id = content.FirstChildContentId;
1330-
while (id > 0)
1323+
// Clear children
1324+
int childId = content.FirstChildContentId;
1325+
if (childId > 0)
13311326
{
1332-
// get the required link node, this ensures that both `link` and `link.Value` are not null
1333-
LinkedNode<ContentNode> link = GetRequiredLinkedNode(id, "child", null);
1334-
ContentNode? linkValue = link.Value; // capture local since clearing in recurse can clear it
1335-
ClearBranchLocked(linkValue); // recurse
1336-
id = linkValue?.NextSiblingContentId ?? 0;
1327+
ContentNode childContent = GetRequiredLinkedNode(childId, "first child", null).Value!;
1328+
ClearBranchLocked(childContent); // recurse
1329+
1330+
// Clear all siblings of child
1331+
int siblingId = childContent.NextSiblingContentId;
1332+
while (siblingId > 0)
1333+
{
1334+
ContentNode siblingContent = GetRequiredLinkedNode(siblingId, "next sibling", null).Value!;
1335+
ClearBranchLocked(siblingContent); // recurse
1336+
siblingId = siblingContent.NextSiblingContentId;
1337+
}
13371338
}
13381339
}
13391340

0 commit comments

Comments
 (0)