From 601d1d3fe3bb8c1f9ce074fbd53938e448146367 Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Sat, 22 Nov 2025 12:17:46 +0200 Subject: [PATCH] Better error message when fetch fails (server temporarily unavailable) Closes #2481 --- AGENTS.md | 1 + app/components/Catcher.tsx | 70 +++++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index a1a640e9e..f4bc88d8b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,6 +3,7 @@ - only rarely use comments, prefer descriptive variable and function names (leave existing comments as is) - if you encounter an existing TODO comment assume it is there for a reason and do not remove it - task is not considered completely until `npm run checks` passes +- normal file structure has constants at the top immediately followed by the main function body of the file. Helpers are used to structure the code and they are at the bottom of the file (then hoisted to the top) ## Commands diff --git a/app/components/Catcher.tsx b/app/components/Catcher.tsx index 42f172a7b..31f45da0c 100644 --- a/app/components/Catcher.tsx +++ b/app/components/Catcher.tsx @@ -4,7 +4,7 @@ import { useRouteError, } from "@remix-run/react"; import * as React from "react"; -import { useCopyToClipboard, useLocation } from "react-use"; +import { useLocation } from "react-use"; import { useUser } from "~/features/auth/core/user"; import { ERROR_GIRL_IMAGE_PATH, @@ -13,6 +13,7 @@ import { } from "~/utils/urls"; import { SendouButton } from "./elements/Button"; import { Image } from "./Image"; +import { RefreshArrowsIcon } from "./icons/RefreshArrows"; import { Main } from "./Main"; export function Catcher() { @@ -20,7 +21,6 @@ export function Catcher() { const user = useUser(); const { revalidate } = useRevalidator(); const location = useLocation(); - const [, copyToClipboard] = useCopyToClipboard(); // refresh user data to make sure it's up to date (e.g. cookie might have been removed, let's show the prompt to log back in) React.useEffect(() => { @@ -29,6 +29,28 @@ export function Catcher() { revalidate(); }, [revalidate, error]); + const isNetworkError = + error instanceof Error && + (error.message.includes("Failed to fetch") || + error.message.includes("NetworkError") || + error.message.includes("Load failed")); + + if (isNetworkError) { + return ( +
+ +

Connection error

+

+ The server was temporarily unavailable. This is usually a brief + network issue. +

+
+ +
+
+ ); + } + if (!isRouteErrorResponse(error)) { const errorText = (() => { if (!(error instanceof Error)) return; @@ -38,26 +60,19 @@ export function Catcher() { return (
- +

Error happened

- It seems like you encountered a bug. Sorry about that! Please share - the diagnostics message below as well as other details (your browser? - what were you doing?) on{" "} - our Discord so it can be fixed. + There was an unexpected error. If this keeps happening, please report + it on our Discord so it can be + fixed. Include the error message below.

{errorText ? (