Skip to content

Improve Sections warning messaging#67977

Open
dariatiurina wants to merge 5 commits into
dotnet:mainfrom
dariatiurina:66831-sections
Open

Improve Sections warning messaging#67977
dariatiurina wants to merge 5 commits into
dotnet:mainfrom
dariatiurina:66831-sections

Conversation

@dariatiurina

@dariatiurina dariatiurina commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Improve Sections warning messaging

Summary

Adds diagnostic logging to the Blazor Sections feature (SectionOutlet / SectionContent) so developers are told when a section is misconfigured — most importantly when the outlet and content are split across a render mode boundary, which Sections does not support. This is purely observational; it does not change how sections resolve or render.

Changes

  • Render mode mismatch warning (LogLevel.Warning, SectionRenderModeMismatch): emitted when a SectionOutlet and a matching SectionContent are both known to a single registry but declare different render modes. The message explains that sections cannot connect across render mode boundaries and the outlet will not display the content once the components become interactive.
  • Orphaned section diagnostics (LogLevel.Debug): SectionOutletWithoutContent and SectionContentWithoutOutlet are emitted when only one half of a section is present. These messages are purely factual (no render mode text), since the common cause is a missing/mismatched section ID rather than a render mode boundary.
  • Diagnostics are logged once per problem episode and re-armed when the condition is resolved, so a section that is fixed and later re-broken is reported again.

Details

  • Registry ownership and logger plumbing. The SectionRegistry now lives on the Renderer instead of the Dispatcher. Renderer retains the ILoggerFactory it is constructed with and creates the registry lazily on first use (SectionRegistry => _sectionRegistry ??= new SectionRegistry(_loggerFactory)), so renderers that never use Sections allocate nothing. RenderHandle exposes the renderer's registry (RenderHandle.SectionRegistry, mirroring the existing ComponentMetrics / ComponentActivitySource accessors), and SectionOutlet / SectionContent obtain it from the render handle when they attach, capturing their render mode at attach time (a component's render mode is stable for its lifetime). The registry receives the factory through its constructor and builds its own logger, so these renderer-level diagnostics route through the renderer's own logging pipeline and require no logger to flow through the Dispatcher.
  • Eager mismatch detection. The mismatch check runs when both halves become known to the same registry (during Subscribe and NotifyContentProviderChanged). Render modes are compared by type so two instances of the same mode (e.g. differing only by prerender flag) are treated as equivalent, while static (null) is distinct from any interactive mode.
  • Deferred orphan detection. Section mutations (AddProvider / RemoveProvider / Subscribe / Unsubscribe) mark the identifier for an orphan check that is evaluated at end-of-batch via Renderer calling OnRenderBatchCompleted() on the registry (a no-op when the registry was never created, i.e. Sections are not in use). Deferring to end-of-batch avoids false positives from transient one-sided states during a batch (e.g. a section-id change is a remove+add pair).
  • Separate log-once latches. Mismatch and orphan use separate "already logged" sets so a section that changes problem type still emits the new diagnostic — e.g. under streaming SSR a SectionOutlet may first render orphaned (its SectionContent hasn't streamed in yet), then have content stream in under a different render mode, and that mismatch warning must still fire.

Testing

  • SectionRegistryTest (new unit tests, driven through a test Renderer): outlet-then-content and content-then-outlet mismatch, static-outlet + interactive-content mismatch, matching modes producing no warning/orphan, and orphaned outlet / orphaned content Debug diagnostics.
  • EndpointHtmlRendererTest.SectionOutletAndContentInDifferentRenderModes_LogsWarningDuringPrerendering (new integration test): prerenders a component with a static SectionOutlet and an InteractiveServer SectionContent through the real EndpointHtmlRenderer with a TestSink, and asserts the mismatch warning is logged during SSR. Backed by a new SectionOutletAndContentWithDifferentRenderModes.razor test component.

Fixes #66831

@dariatiurina
dariatiurina marked this pull request as ready for review July 23, 2026 11:43
@dariatiurina
dariatiurina requested a review from a team as a code owner July 23, 2026 11:43
Copilot AI review requested due to automatic review settings July 23, 2026 11:43
@dariatiurina dariatiurina self-assigned this Jul 23, 2026
@dariatiurina dariatiurina added this to the 11.0-preview7 milestone Jul 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds diagnostic logging for Blazor Sections (SectionOutlet/SectionContent) to warn about render mode mismatches and to emit deferred debug diagnostics for orphaned outlets/contents, with unit/integration test coverage.

Changes:

  • Add SectionRegistry diagnostics: warn on outlet/content render mode mismatches and emit debug logs for orphaned section halves (deferred to end-of-batch).
  • Plumb renderer logging access via Renderer.LoggerFactory and RenderHandle.LoggerFactory, and flush deferred section diagnostics after render batches.
  • Add unit tests (SectionRegistryTest) and an EndpointHtmlRenderer integration test + razor test component.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Components/Components/src/Sections/SectionRegistry.cs Adds logger setup, log-once latches, mismatch detection, and deferred orphan diagnostics flushed at end-of-batch.
src/Components/Components/src/Sections/SectionOutlet.cs Captures outlet render mode at attach and ensures the registry has a logger.
src/Components/Components/src/Sections/SectionContent.cs Captures content render mode at attach and ensures the registry has a logger.
src/Components/Components/src/RenderTree/Renderer.cs Retains ILoggerFactory, exposes it internally, and flushes section diagnostics after render batches.
src/Components/Components/src/RenderHandle.cs Exposes the renderer’s ILoggerFactory to components via RenderHandle.
src/Components/Components/src/Dispatcher.cs Adds SectionRegistryIfExists to avoid allocating a registry when sections aren’t used.
src/Components/Components/test/Sections/SectionRegistryTest.cs New unit tests for mismatch/orphan diagnostics driven via a test renderer.
src/Components/Endpoints/test/EndpointHtmlRendererTest.cs Adds integration test asserting mismatch warning is logged during prerendering; updates helper to accept a logger factory.
src/Components/Endpoints/test/TestComponents/SectionOutletAndContentWithDifferentRenderModes.razor New test component to create a static outlet + interactive content mismatch scenario.

Comment thread src/Components/Components/src/Sections/SectionRegistry.cs
Comment thread src/Components/Components/test/Sections/SectionRegistryTest.cs
@gfoidl gfoidl added the area-blazor Includes: Blazor, Razor Components label Jul 23, 2026
dariatiurina and others added 2 commits July 23, 2026 15:14
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@ilonatommy ilonatommy modified the milestones: 11.0-preview7, 11.0-rc1 Jul 24, 2026
Comment thread src/Components/Components/src/Sections/SectionContent.cs
Comment on lines +109 to +110
// Option A: the active content for this section changed. If a matching outlet exists in a
// different render mode, warn now.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Option A: the active content for this section changed. If a matching outlet exists in a
// different render mode, warn now.


private HashSet<object>? _identifiersPendingOrphanCheck;

// Kept as separate "already logged" sets so a section that changes problem type still emits the new diagnostic. Concrete case: during streaming SSR a SectionOutlet first renders orphaned (its SectionContent hasn't streamed in yet), then the SectionContent streams in under a different render mode; the mismatch warning must still fire even though the orphan was already logged.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Kept as separate "already logged" sets so a section that changes problem type still emits the new diagnostic. Concrete case: during streaming SSR a SectionOutlet first renders orphaned (its SectionContent hasn't streamed in yet), then the SectionContent streams in under a different render mode; the mismatch warning must still fire even though the orphan was already logged.

internal ComponentsMetrics? ComponentMetrics => _componentsMetrics;
internal ComponentsActivitySource? ComponentActivitySource => _componentsActivitySource;

internal ILoggerFactory LoggerFactory => _loggerFactory;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do we use it?

providers.Add(provider);
}

MarkForOrphanCheck(identifier);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue doesn't mention orphan checks. From what I see orphans are supported pattern, e.g. we have tests in src/Components/test/E2ETest/Tests/SectionsTest.cs that check that pattern as passing. This change should not be in the PR scope.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add better warnings and errors for Sections

4 participants