Skip to content

Commit 5e0ae68

Browse files
committed
Fixes
1 parent e536bc2 commit 5e0ae68

File tree

8 files changed

+37
-14
lines changed

8 files changed

+37
-14
lines changed

src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,12 @@ public Task Render(HttpContext context)
3535
private async Task RenderComponentCore(HttpContext context)
3636
{
3737
context.Response.ContentType = RazorComponentResultExecutor.DefaultContentType;
38-
_renderer.InitializeStreamingRenderingFraming(context);
39-
EndpointHtmlRenderer.MarkAsAllowingEnhancedNavigation(context);
38+
var isErrorHandler = context.Features.Get<IExceptionHandlerFeature>() is not null;
39+
_renderer.InitializeStreamingRenderingFraming(context, isErrorHandler);
40+
if (!isErrorHandler)
41+
{
42+
EndpointHtmlRenderer.MarkAsAllowingEnhancedNavigation(context);
43+
}
4044

4145
var endpoint = context.GetEndpoint() ?? throw new InvalidOperationException($"An endpoint must be set on the '{nameof(HttpContext)}'.");
4246

@@ -84,7 +88,7 @@ await EndpointHtmlRenderer.InitializeStandardComponentServicesAsync(
8488
context,
8589
rootComponent,
8690
ParameterView.Empty,
87-
waitForQuiescence: result.IsPost);
91+
waitForQuiescence: result.IsPost || isErrorHandler);
8892

8993
Task quiesceTask;
9094
if (!result.IsPost)
@@ -123,8 +127,11 @@ await EndpointHtmlRenderer.InitializeStandardComponentServicesAsync(
123127
}
124128

125129
// Emit comment containing state.
126-
var componentStateHtmlContent = await _renderer.PrerenderPersistedStateAsync(context);
127-
componentStateHtmlContent.WriteTo(bufferWriter, HtmlEncoder.Default);
130+
if (!isErrorHandler)
131+
{
132+
var componentStateHtmlContent = await _renderer.PrerenderPersistedStateAsync(context);
133+
componentStateHtmlContent.WriteTo(bufferWriter, HtmlEncoder.Default);
134+
}
128135

129136
// Invoke FlushAsync to ensure any buffered content is asynchronously written to the underlying
130137
// response asynchronously. In the absence of this line, the buffer gets synchronously written to the

src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.Streaming.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ internal partial class EndpointHtmlRenderer
1919
private TextWriter? _streamingUpdatesWriter;
2020
private HashSet<int>? _visitedComponentIdsInCurrentStreamingBatch;
2121
private string? _ssrFramingCommentMarkup;
22-
private bool _allowBoundaryMarkers;
22+
private bool _isHandlingErrors;
2323

24-
public void InitializeStreamingRenderingFraming(HttpContext httpContext)
24+
public void InitializeStreamingRenderingFraming(HttpContext httpContext, bool isErrorHandler)
2525
{
26+
_isHandlingErrors = isErrorHandler;
2627
if (IsProgressivelyEnhancedNavigation(httpContext.Request))
2728
{
2829
var id = Guid.NewGuid().ToString();
@@ -202,19 +203,19 @@ protected override void RenderChildComponent(TextWriter output, ref RenderTreeFr
202203
{
203204
var componentId = componentFrame.ComponentId;
204205
var sequenceAndKey = new SequenceAndKey(componentFrame.Sequence, componentFrame.ComponentKey);
205-
WriteComponentHtml(componentId, output, _allowBoundaryMarkers, sequenceAndKey);
206+
WriteComponentHtml(componentId, output, allowBoundaryMarkers: true, sequenceAndKey);
206207
}
207208

208209
private void WriteComponentHtml(int componentId, TextWriter output, bool allowBoundaryMarkers, SequenceAndKey sequenceAndKey = default)
209210
{
210211
_visitedComponentIdsInCurrentStreamingBatch?.Add(componentId);
211212

212213
var componentState = (EndpointComponentState)GetComponentState(componentId);
213-
var renderBoundaryMarkers = allowBoundaryMarkers && componentState.StreamRendering;
214+
var renderBoundaryMarkers = allowBoundaryMarkers && componentState.StreamRendering && !_isHandlingErrors;
214215

215216
ComponentEndMarker? endMarkerOrNull = default;
216217

217-
if (componentState.Component is SSRRenderModeBoundary boundary)
218+
if (componentState.Component is SSRRenderModeBoundary boundary && !_isHandlingErrors)
218219
{
219220
var marker = boundary.ToMarker(_httpContext, sequenceAndKey.Sequence, sequenceAndKey.Key);
220221
endMarkerOrNull = marker.ToEndMarker();
@@ -246,7 +247,7 @@ private void WriteComponentHtml(int componentId, TextWriter output, bool allowBo
246247
output.Write("-->");
247248
}
248249

249-
if (endMarkerOrNull is { } endMarker)
250+
if (endMarkerOrNull is { } endMarker && !_isHandlingErrors)
250251
{
251252
var serializedEndRecord = JsonSerializer.Serialize(endMarker, ServerComponentSerializationSettings.JsonSerializationOptions);
252253
output.Write("<!--Blazor:");

src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
using Microsoft.AspNetCore.Components.Rendering;
1313
using Microsoft.AspNetCore.Components.RenderTree;
1414
using Microsoft.AspNetCore.Components.Routing;
15-
using Microsoft.AspNetCore.Diagnostics;
1615
using Microsoft.AspNetCore.Http;
1716
using Microsoft.AspNetCore.Http.Extensions;
1817
using Microsoft.AspNetCore.Routing;
@@ -60,7 +59,6 @@ private void SetHttpContext(HttpContext httpContext)
6059
if (_httpContext is null)
6160
{
6261
_httpContext = httpContext;
63-
_allowBoundaryMarkers = _httpContext.Features.Get<IExceptionHandlerFeature>() is null;
6462
}
6563
else if (_httpContext != httpContext)
6664
{

src/Components/Endpoints/src/Results/RazorComponentResultExecutor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Buffers;
66
using System.Text;
77
using System.Text.Encodings.Web;
8+
using Microsoft.AspNetCore.Diagnostics;
89
using Microsoft.AspNetCore.Http;
910
using Microsoft.AspNetCore.WebUtilities;
1011
using Microsoft.Extensions.DependencyInjection;
@@ -46,7 +47,8 @@ private static Task RenderComponentToResponse(
4647
var endpointHtmlRenderer = httpContext.RequestServices.GetRequiredService<EndpointHtmlRenderer>();
4748
return endpointHtmlRenderer.Dispatcher.InvokeAsync(async () =>
4849
{
49-
endpointHtmlRenderer.InitializeStreamingRenderingFraming(httpContext);
50+
var isErrorHandler = httpContext.Features.Get<IExceptionHandlerFeature>() is not null;
51+
endpointHtmlRenderer.InitializeStreamingRenderingFraming(httpContext, isErrorHandler);
5052
EndpointHtmlRenderer.MarkAsAllowingEnhancedNavigation(httpContext);
5153

5254
// We could pool these dictionary instances if we wanted, and possibly even the ParameterView

src/Components/test/E2ETest/ServerRenderingTests/ErrorHandlingTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public void RendersExceptionFromComponent()
3131
Browser.FindElements(By.CssSelector(".text-danger")),
3232
item => Assert.Equal("Error.", item.Text),
3333
item => Assert.Equal("An error occurred while processing your request.", item.Text));
34+
Browser.Equal("False", () => Browser.FindElement(By.Id("is-interactive-server")).Text);
3435
}
3536

3637
private void GoTo(string relativePath)

src/Components/test/testassets/Components.TestServer/Components.TestServer.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,10 @@
4343
</AssemblyAttribute>
4444
</ItemGroup>
4545

46+
<ItemGroup>
47+
<Content Update="RazorComponents\Pages\ErrorLayout.razor">
48+
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
49+
</Content>
50+
</ItemGroup>
51+
4652
</Project>

src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Error.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@page "/Error"
2+
@layout ErrorLayout
23
@using System.Diagnostics
34

45
<PageTitle>Error</PageTitle>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@inherits Microsoft.AspNetCore.Components.LayoutComponentBase
2+
3+
<ServerInteractiveCounter />
4+
5+
<div>
6+
@Body
7+
</div>

0 commit comments

Comments
 (0)