Do you have a useful 404 error page?

Last updated by Tiago Araújo [SSW] over 2 years ago.See history

Error page, you say? You worked hard to make sure my site has no errors!! Well, surfers don't always type URLs accurately. No website is immune to such errors.

A well-designed custom error page encourages surfers to remain in your site and help them to the right page. Although it's possible to redirect error codes straight to your homepage, that doesn't tell visitors what's going on. It's more user-friendly to explain that there was a problem and provide some alternatives. Supply a link to your home page or other links, or offer your site's search function if you have one.

404 bad
Figure: Bad example - Unhandled error

404 good
Figure: Good example - Custom error page

.NET Core (Server-Side)

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    // Turn on error handling middleware
    app.UseExceptionHandler("/Error");
}

// Use status code page routes (eg. /Error/404, /Error/500)
app.UseStatusCodePagesWithReExecute("/Error/{0}");

// Turn on routing
app.UseRouting();

// Map your endpoints
app.MapGet("/Error/{statusCode}", async (HttpContext httpContext, int statusCode) =>
{
    // Preserve the status code in the response
    httpContext.Response.StatusCode = statusCode;

    if (statusCode == 404)
    {
        // Return a custom "404 Not Found" response        
        httpContext.Response.ContentType = "text/html";
        await httpContext.Response.WriteAsync("<h1>Sorry, we couldn’t find that page.</h1>");
    }
    else
    {
        // For other status codes, return a generic error
        httpContext.Response.ContentType = "text/html";
        await httpContext.Response.WriteAsync($"<h1>An error occurred (status code: {statusCode}).</h1>");
    }
});

// Any endpoint mappings or other middleware
app.MapGet("/", () => "Hello World!");

app.Run();

Figure: Good example - Wildcard routing of unrecognised paths

Angular (Client-Side)

Inside your Angular project you can update the app-routing module to catch any unrecognised paths

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { NotFoundComponent } from './not-found/not-found.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  // ... your other routes here ...
  { path: '**', component: NotFoundComponent } // wildcard route
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { useHash: false })],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Figure: Good example - Wildcard routing of unrecognised paths

<!-- not-found.component.html -->
<div class="not-found">
  <h1>404 - Page Not Found</h1>
  <p>We’re sorry, but we couldn’t find the page you requested.</p>
  <a routerLink="/">Go back to Home</a>
</div>

Figure: Good example - The custom 404 html page

React.js (Client-Side)

import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './Home';
import NotFound from './NotFound';

function App() {
  return (
    <Router>
      <Routes>
        {/* Your valid routes: */}
        <Route path="/" element={<Home />} />
        {/* Add other valid routes here */}

        {/* "Catch-all" or wildcard route for anything that doesn't match */}
        <Route path="*" element={<NotFound />} />
      </Routes>
    </Router>
  );
}

export default App;

Figure: Good example - The custom 404 pages

ASP .NET

<customErrors mode="Off"></customErrors>

Figure: Bad example - The default code on web.config

<customErrors mode="RemoteOnly" defaultRedirect="/ssw/ErrorPage.aspx">
<error statusCode="404" redirect="/ssw/SSWCustomError404.aspx">
</customErrors>

Figure: Good example - The custom code in the web.config

For ASP.NET website, the detailed information would be presented to the remote machines when an unhandled error occurs if the customErrors mode is off.

This error information is useful for the developer to do debugging. However, it would leak out some confidential information which could be used to get into your system by the hackers. We can assume that if a SQL exception occurs by accident, which may expose database sensitive information (e.g. connection string; SQL script). So, to prevent these leaks, you should set the "mode" attribute of the tag <customerrors> to "RemoteOnly" or "On" in the web.config file and create a user-friendly customized error page to replace the detailed error information.

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"></customErrors>

Figure: Good example - Turning on "customErrors" protects sensitive information against Hacker


We open source.Loving SSW Rules? Star us on GitHub. Star
Stand by... we're migrating this site to TinaCMS