1- // The styles need to be imported at the beginning, so that the layers are correctly set up
2- // eslint-disable-next-line prettier/prettier
1+ // sort-imports-ignore
2+ import "./styles" ;
3+ // NOTE: The sort-imports-ignore is needed here to prevent css layers from not being loaded in the correct order, feel free to remove the ignore momentarily to sort imports
4+
35// import { LinksFunction } from "@remix-run/react/dist/routeModules";
46import { Provider as RadixTooltip } from "@radix-ui/react-tooltip" ;
57import { captureRemixErrorBoundaryError , withSentry } from "@sentry/remix" ;
@@ -8,6 +10,11 @@ import {
810 type publicEnvVariablesType ,
911} from "cyberstorm/security/publicEnvVariables" ;
1012import { LinkLibrary } from "cyberstorm/utils/LinkLibrary" ;
13+ import { NimbusAwaitErrorElement } from "cyberstorm/utils/errors/NimbusErrorBoundary" ;
14+ import {
15+ type UserFacingErrorPayload ,
16+ parseUserFacingErrorPayload ,
17+ } from "cyberstorm/utils/errors/userFacingErrorResponse" ;
1118import { type ReactNode , Suspense , memo , useEffect , useRef } from "react" ;
1219import {
1320 Await ,
@@ -35,8 +42,6 @@ import {
3542 isRecord ,
3643} from "@thunderstore/cyberstorm" ;
3744import { Toast } from "@thunderstore/cyberstorm" ;
38- import "@thunderstore/cyberstorm-theme/css" ;
39- import "@thunderstore/cyberstorm/css" ;
4045import { type CurrentUser } from "@thunderstore/dapper" ;
4146import { DapperTs } from "@thunderstore/dapper-ts" ;
4247import { type RequestConfig } from "@thunderstore/thunderstore-api" ;
@@ -50,10 +55,7 @@ import {
5055
5156import type { Route } from "./+types/root" ;
5257import { Footer } from "./commonComponents/Footer/Footer" ;
53- // Annoying prettier issue, where it wants to insert styles import here
54- // eslint-disable-next-line prettier/prettier
5558import { NavigationWrapper } from "./commonComponents/Navigation/NavigationWrapper" ;
56- import "./styles/index.css" ;
5759
5860// REMIX TODO: https://remix.run/docs/en/main/route/links
5961// export const links: LinksFunction = () => [{ rel: "stylesheet", href: styles }];
@@ -621,18 +623,36 @@ export function ErrorBoundary() {
621623 console . log ( error ) ;
622624 }
623625 const isResponseError = isRouteErrorResponse ( error ) ;
626+ let payload : UserFacingErrorPayload | null = null ;
627+
628+ if ( isResponseError ) {
629+ payload = parseUserFacingErrorPayload ( error . data ) ;
630+ }
631+
632+ const statusCode = payload ?. status ?? ( isResponseError ? error . status : 500 ) ;
633+ const headline =
634+ payload ?. headline ??
635+ ( isResponseError
636+ ? error . statusText || `Error ${ error . status } `
637+ : "Internal server error" ) ;
638+
639+ const fallbackDescription =
640+ isResponseError && typeof error . data === "string"
641+ ? dedupeDescription ( headline , error . data )
642+ : undefined ;
643+
644+ const description = payload ?. description ?? fallbackDescription ;
645+ const showDefaultFlavor = ! payload && ! isResponseError ;
624646 return (
625647 < div className = "error" >
626- < div
627- className = "error__glitch"
628- data-text = { isResponseError ? error . status : 500 }
629- >
630- < span > { isResponseError ? error . status : 500 } </ span >
648+ < div className = "error__glitch" data-text = { statusCode } >
649+ < span > { statusCode } </ span >
631650 </ div >
632651 < div className = "error__description" >
633- { isResponseError ? error . data : "Internal server error" }
652+ < strong > { headline } </ strong >
653+ { description ? < div > { description } </ div > : null }
634654 </ div >
635- { ! isResponseError && (
655+ { showDefaultFlavor && (
636656 < div className = "error__flavor" >
637657 Beep boop. Server something error happens.
638658 </ div >
@@ -641,6 +661,26 @@ export function ErrorBoundary() {
641661 ) ;
642662}
643663
664+ function dedupeDescription (
665+ headline : string ,
666+ description : string | undefined
667+ ) : string | undefined {
668+ if ( ! description ) {
669+ return undefined ;
670+ }
671+
672+ const trimmedDescription = description . trim ( ) ;
673+ if ( ! trimmedDescription ) {
674+ return undefined ;
675+ }
676+
677+ if ( trimmedDescription . toLowerCase ( ) === headline . trim ( ) . toLowerCase ( ) ) {
678+ return undefined ;
679+ }
680+
681+ return trimmedDescription ;
682+ }
683+
644684// Temporary solution for implementing ads
645685// REMIX TODO: Move to dynamic html
646686function AdsInit ( ) {
@@ -739,7 +779,10 @@ function getCommunityBreadcrumb(
739779 </ span >
740780 }
741781 >
742- < Await resolve = { communityPage . data . community } >
782+ < Await
783+ resolve = { communityPage . data . community }
784+ errorElement = { < NimbusAwaitErrorElement /> }
785+ >
743786 { ( resolvedValue ) => {
744787 let label = undefined ;
745788 let icon = undefined ;
0 commit comments