Skip to content

Commit 4d097f1

Browse files
committed
Fix for 404 not found.
1 parent 91c6e59 commit 4d097f1

5 files changed

Lines changed: 131 additions & 27 deletions

File tree

Lines changed: 83 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,99 @@
11
@page "/Error"
2+
@page "/not-found"
3+
@layout PlaygroundLayout
24
@using System.Diagnostics
5+
@inject NavigationManager Navigation
36

4-
<PageTitle>Error</PageTitle>
7+
<PageTitle>@ErrorTitle</PageTitle>
58

6-
<h1 class="text-danger">Error.</h1>
7-
<h2 class="text-danger">An error occurred while processing your request.</h2>
9+
<MudContainer MaxWidth="MaxWidth.Medium" Class="mt-8">
10+
<MudPaper Elevation="3" Class="pa-8">
11+
<div class="d-flex flex-column align-center">
12+
<MudIcon Icon="@Icons.Material.Filled.ErrorOutline" Color="Color.Error" Style="font-size: 6rem;" Class="mb-4" />
813

9-
@if (ShowRequestId)
10-
{
11-
<p>
12-
<strong>Request ID:</strong> <code>@RequestId</code>
13-
</p>
14-
}
14+
<MudText Typo="Typo.h3" Color="Color.Error" Class="mb-2">@ErrorTitle</MudText>
15+
<MudText Typo="Typo.h6" Color="Color.Secondary" Class="mb-4">@ErrorMessage</MudText>
16+
17+
@if (ShowRequestId)
18+
{
19+
<MudAlert Severity="Severity.Info" Class="mb-4">
20+
<strong>Request ID:</strong> <code>@RequestId</code>
21+
</MudAlert>
22+
}
1523

16-
<h3>Development Mode</h3>
17-
<p>
18-
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
19-
</p>
20-
<p>
21-
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
22-
It can result in displaying sensitive information from exceptions to end users.
23-
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
24-
and restarting the app.
25-
</p>
24+
@if (StatusCode == 404)
25+
{
26+
<MudText Typo="Typo.body1" Class="mb-4 text-center">
27+
The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.
28+
</MudText>
29+
<MudButton Variant="Variant.Filled" Color="Color.Primary" Href="/" StartIcon="@Icons.Material.Filled.Home">
30+
Go to Home
31+
</MudButton>
32+
}
33+
else
34+
{
35+
<MudText Typo="Typo.h6" Class="mt-4 mb-2">Development Mode</MudText>
36+
<MudText Typo="Typo.body2" Class="mb-2">
37+
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
38+
</MudText>
39+
<MudAlert Severity="Severity.Warning" Class="mt-4">
40+
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
41+
It can result in displaying sensitive information from exceptions to end users.
42+
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
43+
and restarting the app.
44+
</MudAlert>
45+
}
46+
</div>
47+
</MudPaper>
48+
</MudContainer>
2649

2750
@code{
2851
[CascadingParameter]
2952
private HttpContext? HttpContext { get; set; }
3053

54+
[Parameter]
55+
public int? StatusCodeParameter { get; set; }
56+
3157
private string? RequestId { get; set; }
3258
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
59+
private int? StatusCode { get; set; }
3360

34-
protected override void OnInitialized() =>
61+
private string ErrorTitle => StatusCode switch
62+
{
63+
404 => "404 - Page Not Found",
64+
_ => "Error"
65+
};
66+
67+
private string ErrorMessage => StatusCode switch
68+
{
69+
404 => "The page you requested could not be found.",
70+
_ => "An error occurred while processing your request."
71+
};
72+
73+
protected override void OnInitialized()
74+
{
3575
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
76+
77+
// First check if status code was passed as a parameter
78+
if (StatusCodeParameter.HasValue)
79+
{
80+
StatusCode = StatusCodeParameter;
81+
}
82+
else
83+
{
84+
// Check for status code in query parameters
85+
var uri = new Uri(Navigation.Uri);
86+
var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
87+
var statusParam = query["status"];
88+
if (!string.IsNullOrEmpty(statusParam) && int.TryParse(statusParam, out var status))
89+
{
90+
StatusCode = status;
91+
}
92+
else
93+
{
94+
// Default to 404 if no status code is provided (e.g., when used as NotFoundPage)
95+
StatusCode = 404;
96+
}
97+
}
98+
}
3699
}

src/Playground/Playground.Blazor/Components/Pages/SimpleLogin.razor

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
@inject IHttpClientFactory HttpClientFactory
1010
@inject AuthenticationStateProvider AuthenticationStateProvider
1111
@inject IWebHostEnvironment Environment
12+
@inject ISnackbar Snackbar
1213

1314
<PageTitle>Login</PageTitle>
1415
<div class="login-page">
@@ -130,6 +131,25 @@
130131

131132
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
132133
_isAuthenticated = authState.User.Identity?.IsAuthenticated == true;
134+
135+
// Check for error message in query parameters
136+
var uri = new Uri(Navigation.Uri);
137+
var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
138+
var errorMessage = query["error"];
139+
if (!string.IsNullOrEmpty(errorMessage))
140+
{
141+
Snackbar.Add(errorMessage, Severity.Error);
142+
// Remove the error parameter from URL to avoid showing it again on refresh
143+
try
144+
{
145+
Navigation.NavigateTo("/login", replace: true);
146+
}
147+
catch (NavigationException)
148+
{
149+
// NavigationException is expected when NavigateTo interrupts the render cycle
150+
// The navigation will still succeed
151+
}
152+
}
133153
}
134154

135155
protected override void OnAfterRender(bool firstRender)
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
@using FSH.Playground.Blazor.Components.Layout
2+
@using FSH.Playground.Blazor.Components.Pages
23
@using Microsoft.AspNetCore.Components.Authorization
34

4-
<Router AppAssembly="typeof(Program).Assembly">
5+
<Router AppAssembly="typeof(Program).Assembly" NotFoundPage="typeof(Error)">
56
<Found Context="routeData">
67
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(PlaygroundLayout)">
78
<NotAuthorized>
@@ -13,9 +14,4 @@
1314
</AuthorizeRouteView>
1415
<FocusOnNavigate RouteData="routeData" Selector="h1" />
1516
</Found>
16-
<NotFound>
17-
<LayoutView Layout="typeof(PlaygroundLayout)">
18-
<p>Sorry, there's nothing at this address.</p>
19-
</LayoutView>
20-
</NotFound>
2117
</Router>

src/Playground/Playground.Blazor/Program.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@
129129
app.UseHsts();
130130
}
131131

132+
// Status Code Pages Middleware - handles 404s by re-executing the request pipeline
133+
// This prevents the browser from showing its default 404 page
134+
app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
135+
132136
// Simple health endpoints for ALB/ECS
133137
app.MapGet("/health/ready", () => Results.Ok(new { status = "Healthy" }))
134138
.AllowAnonymous();

src/Playground/Playground.Blazor/Services/SimpleBffAuth.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,28 @@ public static void MapSimpleBffAuthEndpoints(this WebApplication app)
8989
}
9090
catch (ApiException ex) when (ex.StatusCode == 401)
9191
{
92-
return Results.Unauthorized();
92+
// Extract error message from ProblemDetails response
93+
string errorMessage = "Invalid credentials";
94+
if (!string.IsNullOrEmpty(ex.Response))
95+
{
96+
try
97+
{
98+
var problemDetails = System.Text.Json.JsonSerializer.Deserialize<System.Text.Json.JsonElement>(ex.Response);
99+
if (problemDetails.TryGetProperty("detail", out var detail))
100+
{
101+
errorMessage = detail.GetString() ?? errorMessage;
102+
}
103+
}
104+
catch
105+
{
106+
// If parsing fails, use default message
107+
}
108+
}
109+
110+
logger.LogWarning("Login failed: {ErrorMessage}", errorMessage);
111+
112+
// Redirect to login page with error message as query parameter
113+
return Results.Redirect($"/login?error={Uri.EscapeDataString(errorMessage)}");
93114
}
94115
catch (Exception ex)
95116
{

0 commit comments

Comments
 (0)