Skip to content

Commit 9e341ed

Browse files
authored
[Blazor] Generate better error message(s) when we encounter an unknown RenderTreeFrameType (#63230)
Print the component path and the sequence of RenderTreeFrames up to the current frame for better diagnostics.
1 parent 64804f9 commit 9e341ed

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,10 +746,50 @@ private static void AppendDiffEntriesForFramesWithSameSequence(
746746
// We don't handle attributes here, they have their own diff logic.
747747
// See AppendDiffEntriesForAttributeFrame
748748
default:
749-
throw new NotImplementedException($"Encountered unsupported frame type during diffing: {newTree[newFrameIndex].FrameTypeField}");
749+
throw new NotImplementedException(CreateDiffErrorMessage(ref diffContext, newFrameIndex));
750750
}
751751
}
752752

753+
private static string CreateDiffErrorMessage(ref DiffContext diffContext, int newFrameIndex)
754+
{
755+
var newTree = diffContext.NewTree;
756+
var unsupportedFrameType = newTree[newFrameIndex].FrameTypeField;
757+
758+
// Build component hierarchy path
759+
var componentPath = BuildComponentPath(diffContext.Renderer, diffContext.ComponentId);
760+
761+
// Build frame types descriptor
762+
var frameTypesDescriptor = BuildFrameTypeDescriptor(newTree, newFrameIndex);
763+
764+
return $"Encountered an unsupported frame type during diffing {unsupportedFrameType} for Component Path: '{componentPath}' on tree with length '{newTree.Length}' and contents '{frameTypesDescriptor}'.";
765+
}
766+
767+
private static string BuildFrameTypeDescriptor(RenderTreeFrame[] renderTree, int frameIndex)
768+
{
769+
var frameTypes = new List<string>();
770+
for (var i = 0; i <= frameIndex && i < renderTree.Length; i++)
771+
{
772+
frameTypes.Add(renderTree[i].FrameTypeField.ToString());
773+
}
774+
775+
return string.Join(", ", frameTypes);
776+
}
777+
778+
private static string BuildComponentPath(Renderer renderer, int componentId)
779+
{
780+
var componentPath = new List<string>();
781+
var currentComponentState = renderer.GetRequiredComponentState(componentId);
782+
783+
while (currentComponentState is not null)
784+
{
785+
var componentType = currentComponentState.Component.GetType();
786+
componentPath.Insert(0, componentType.Name);
787+
currentComponentState = currentComponentState.ParentComponentState;
788+
}
789+
790+
return string.Join(" -> ", componentPath);
791+
}
792+
753793
// This should only be called for attributes that have the same name. This is an
754794
// invariant maintained by the callers.
755795
private static void AppendDiffEntriesForAttributeFrame(

src/Components/Components/src/RenderTree/Renderer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ private ulong FindLatestEventHandlerIdInChain(ulong eventHandlerId)
758758
return eventHandlerId;
759759
}
760760

761-
private ComponentState GetRequiredComponentState(int componentId)
761+
internal ComponentState GetRequiredComponentState(int componentId)
762762
=> _componentStateById.TryGetValue(componentId, out var componentState)
763763
? componentState
764764
: throw new ArgumentException($"The renderer does not have a component with ID {componentId}.");

0 commit comments

Comments
 (0)