feat(portal): Add styled errors pages (404, 422, 500) (#4231)

Closes #2136 

## Screenshots for `404` and `500`

<img width="781" alt="Screenshot 2024-03-20 at 1 16 46 PM"
src="https://github.com/firezone/firezone/assets/2646332/e08e338f-b5b5-4a6a-adb8-b53fe9e8e137">

<img width="916" alt="Screenshot 2024-03-20 at 1 16 30 PM"
src="https://github.com/firezone/firezone/assets/2646332/e19238bf-804d-4f60-bbb3-8cf3f4c89d1f">
This commit is contained in:
Brian Manifold
2024-03-22 11:26:00 -04:00
committed by GitHub
parent 48b788a46d
commit f5286d0927
8 changed files with 175 additions and 8 deletions

View File

@@ -0,0 +1,13 @@
defmodule Web.ErrorController do
use Web, :controller
def show(_conn, params) do
case params["code"] do
"404" -> raise Web.LiveErrors.NotFoundError
"422" -> raise Web.LiveErrors.InvalidRequestError
"500" -> raise "internal server error"
end
raise "unknown error"
end
end

View File

@@ -8,7 +8,7 @@ defmodule Web.ErrorHTML do
# * lib/web_web/controllers/error_html/404.html.heex
# * lib/web_web/controllers/error_html/500.html.heex
#
# embed_templates "error_html/*"
embed_templates "error_html/*"
# The default is to render a plain text page based on
# the template name. For example, "404.html" becomes

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=client-width, initial-scale=1" />
<link rel="icon" href={~p"/favicon.ico"} sizes="any" />
<link rel="icon" href={~p"/images/favicon.svg"} type="image/svg+xml" />
<link rel="apple-touch-icon" href={~p"/images/apple-touch-icon.png"} />
<link rel="manifest" href={~p"/site.webmanifest"} />
<meta name="theme-color" content="#331700" />
<meta name="csrf-token" content={get_csrf_token()} />
<title>404 Not Found</title>
<link
phx-track-static
rel="stylesheet"
nonce={@conn.private.csp_nonce}
href={~p"/assets/app.css"}
/>
<script
defer
phx-track-static
type="text/javascript"
nonce={@conn.private.csp_nonce}
src={~p"/assets/app.js"}
>
</script>
</head>
<body class="bg-neutral-50">
<div class="flex items-center h-screen p-16 bg-gray-50">
<div class="container mx-auto flex flex-col items-center">
<div class="flex flex-col gap-6 max-w-md text-center">
<img src="/images/logo.svg" class="mr-5 h-32" alt="Firezone Logo" />
<h2 class="font-extrabold text-9xl text-primary-600">
<span class="sr-only">Error</span>404
</h2>
<p class="text-2xl md:text-3xl">Sorry, we couldn't find this page.</p>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=client-width, initial-scale=1" />
<link rel="icon" href={~p"/favicon.ico"} sizes="any" />
<link rel="icon" href={~p"/images/favicon.svg"} type="image/svg+xml" />
<link rel="apple-touch-icon" href={~p"/images/apple-touch-icon.png"} />
<link rel="manifest" href={~p"/site.webmanifest"} />
<meta name="theme-color" content="#331700" />
<meta name="csrf-token" content={get_csrf_token()} />
<title>422 Error</title>
<link
phx-track-static
rel="stylesheet"
nonce={@conn.private.csp_nonce}
href={~p"/assets/app.css"}
/>
<script
defer
phx-track-static
type="text/javascript"
nonce={@conn.private.csp_nonce}
src={~p"/assets/app.js"}
>
</script>
</head>
<body class="bg-neutral-50">
<div class="flex items-center h-screen p-16 bg-gray-50">
<div class="container mx-auto flex flex-col items-center">
<div class="flex flex-col gap-6 max-w-md text-center">
<img src="/images/logo.svg" class="mr-5 h-32" alt="Firezone Logo" />
<h2 class="font-extrabold text-9xl text-primary-600">
<span class="sr-only">Error</span>422
</h2>
<p class="text-2xl md:text-3xl">
Something went wrong. We've already been notified and will get it fixed as soon as possible.
</p>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=client-width, initial-scale=1" />
<link rel="icon" href={~p"/favicon.ico"} sizes="any" />
<link rel="icon" href={~p"/images/favicon.svg"} type="image/svg+xml" />
<link rel="apple-touch-icon" href={~p"/images/apple-touch-icon.png"} />
<link rel="manifest" href={~p"/site.webmanifest"} />
<meta name="theme-color" content="#331700" />
<meta name="csrf-token" content={get_csrf_token()} />
<title>500 Error</title>
<link
phx-track-static
rel="stylesheet"
nonce={@conn.private.csp_nonce}
href={~p"/assets/app.css"}
/>
<script
defer
phx-track-static
type="text/javascript"
nonce={@conn.private.csp_nonce}
src={~p"/assets/app.js"}
>
</script>
</head>
<body class="bg-neutral-50">
<div class="flex items-center h-screen p-16 bg-gray-50">
<div class="container mx-auto flex flex-col items-center">
<div class="flex flex-col gap-6 max-w-md text-center">
<img src="/images/logo.svg" class="mr-5 h-32" alt="Firezone Logo" />
<h2 class="font-extrabold text-9xl text-primary-600">
<span class="sr-only">Error</span>500
</h2>
<p class="text-2xl md:text-3xl">
Something went wrong. We've already been notified and will get it fixed as soon as possible.
</p>
</div>
</div>
</div>
</body>
</html>

View File

@@ -56,6 +56,12 @@ defmodule Web.Router do
pipe_through [:public]
forward "/mailbox", Plug.Swoosh.MailboxPreview
end
scope "/error", Web do
pipe_through [:public]
get "/:code", ErrorController, :show
end
end
scope "/sign_up", Web do

View File

@@ -118,7 +118,7 @@ defmodule Web.Acceptance.AuthTest do
|> Auth.authenticate(identity)
|> visit(~p"/#{account}/actors")
assert text(session) == "Not Found"
assert text(session) =~ "Sorry, we couldn't find this page"
assert_path(session, ~p"/#{account}/actors")
end

View File

@@ -1,14 +1,32 @@
defmodule Web.ErrorHTMLTest do
use Web.ConnCase, async: true
# Bring render_to_string/4 for testing custom views
import Phoenix.Template
test "renders 404.html", %{conn: conn} do
{_code, _headers, body} =
assert_error_sent 404, fn ->
get(conn, ~p"/error/404")
end
test "renders 404.html" do
assert render_to_string(Web.ErrorHTML, "404", "html", []) == "Not Found"
assert body =~ "Sorry, we couldn't find this page"
end
test "renders 500.html" do
assert render_to_string(Web.ErrorHTML, "500", "html", []) == "Internal Server Error"
test "renders 422.html", %{conn: conn} do
{_code, _headers, body} =
assert_error_sent 422, fn ->
get(conn, ~p"/error/422")
end
assert body =~ "Something went wrong"
assert body =~ "We've already been notified and will get it fixed as soon as possible"
end
test "renders 500.html", %{conn: conn} do
{_code, _headers, body} =
assert_error_sent 500, fn ->
get(conn, ~p"/error/500")
end
assert body =~ "Something went wrong"
assert body =~ "We've already been notified and will get it fixed as soon as possible"
end
end