diff --git a/apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.css b/apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.css index 4584cba61..61ca087eb 100644 --- a/apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.css +++ b/apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.css @@ -2,4 +2,17 @@ .package-changelog__skeleton { height: 500px; } + + .package-changelog__error { + display: flex; + flex-direction: column; + gap: 1rem; + align-items: flex-start; + padding: 3rem 0; + } + + .package-changelog__error-description { + max-width: 40rem; + color: var(--Color-text-muted, rgb(180 189 255 / 0.8)); + } } diff --git a/apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx b/apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx index 2b3c08777..b6c5dfde6 100644 --- a/apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx +++ b/apps/cyberstorm-remix/app/p/tabs/Changelog/Changelog.tsx @@ -10,39 +10,49 @@ import { SkeletonBox } from "@thunderstore/cyberstorm"; import { DapperTs } from "@thunderstore/dapper-ts"; import "./Changelog.css"; +import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError"; +import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings"; +import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse"; +import { + NimbusAwaitErrorElement, + NimbusDefaultRouteErrorBoundary, +} from "cyberstorm/utils/errors/NimbusErrorBoundary"; +import { getLoaderTools } from "cyberstorm/utils/getLoaderTools"; export async function loader({ params }: LoaderFunctionArgs) { if (params.namespaceId && params.packageId) { - const publicEnvVariables = getPublicEnvVariables(["VITE_API_URL"]); - const dapper = new DapperTs(() => { - return { - apiHost: publicEnvVariables.VITE_API_URL, - sessionId: undefined, - }; - }); - return { - changelog: dapper.getPackageChangelog( + const { dapper } = getLoaderTools(); + try { + const changelog = await dapper.getPackageChangelog( params.namespaceId, params.packageId - ), - }; + ); + + return { + changelog, + }; + } catch (error) { + handleLoaderError(error, { + mappings: [ + createNotFoundMapping( + "Changelog not available.", + "We could not find a changelog for this package." + ), + ], + }); + } } - return { - status: "error", - message: "Failed to load changelog", - changelog: { html: "" }, - }; + throwUserFacingPayloadResponse({ + headline: "Changelog not available.", + description: "We could not find a changelog for this package.", + category: "not_found", + status: 404, + }); } -export async function clientLoader({ params }: LoaderFunctionArgs) { +export function clientLoader({ params }: LoaderFunctionArgs) { if (params.namespaceId && params.packageId) { - const tools = getSessionTools(); - const dapper = new DapperTs(() => { - return { - apiHost: tools?.getConfig().apiHost, - sessionId: tools?.getConfig().sessionId, - }; - }); + const { dapper } = getLoaderTools(); return { changelog: dapper.getPackageChangelog( params.namespaceId, @@ -50,27 +60,22 @@ export async function clientLoader({ params }: LoaderFunctionArgs) { ), }; } - return { - status: "error", - message: "Failed to load changelog", - changelog: { html: "" }, - }; + throwUserFacingPayloadResponse({ + headline: "Changelog not available.", + description: "We could not find a changelog for this package.", + category: "not_found", + status: 404, + }); } export default function Changelog() { - const { status, message, changelog } = useLoaderData< - typeof loader | typeof clientLoader - >(); + const { changelog } = useLoaderData(); - if (status === "error") return
{message}
; return ( } > - Error occurred while loading changelog} - > + }> {(resolvedValue) => ( <>
@@ -85,3 +90,7 @@ export default function Changelog() { ); } + +export function ErrorBoundary() { + return ; +}