|
1 | 1 | import { Await, type LoaderFunctionArgs } from "react-router"; |
2 | 2 | import { useLoaderData } from "react-router"; |
3 | | -import { DapperTs } from "@thunderstore/dapper-ts"; |
4 | | -import { |
5 | | - getPublicEnvVariables, |
6 | | - getSessionTools, |
7 | | -} from "cyberstorm/security/publicEnvVariables"; |
8 | 3 | import { Suspense } from "react"; |
9 | 4 | import { SkeletonBox } from "@thunderstore/cyberstorm"; |
10 | 5 | import "./Readme.css"; |
| 6 | +import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError"; |
| 7 | +import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings"; |
| 8 | +import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse"; |
| 9 | +import { |
| 10 | + NimbusAwaitErrorElement, |
| 11 | + NimbusDefaultRouteErrorBoundary, |
| 12 | +} from "cyberstorm/utils/errors/NimbusErrorBoundary"; |
| 13 | +import { getLoaderTools } from "cyberstorm/utils/getLoaderTools"; |
11 | 14 |
|
12 | 15 | export async function loader({ params }: LoaderFunctionArgs) { |
13 | 16 | if (params.namespaceId && params.packageId && params.packageVersion) { |
14 | | - const publicEnvVariables = getPublicEnvVariables(["VITE_API_URL"]); |
15 | | - const dapper = new DapperTs(() => { |
16 | | - return { |
17 | | - apiHost: publicEnvVariables.VITE_API_URL, |
18 | | - sessionId: undefined, |
19 | | - }; |
20 | | - }); |
21 | | - return { |
22 | | - readme: await dapper.getPackageReadme( |
| 17 | + const { dapper } = getLoaderTools(); |
| 18 | + try { |
| 19 | + const readme = await dapper.getPackageReadme( |
23 | 20 | params.namespaceId, |
24 | 21 | params.packageId, |
25 | 22 | params.packageVersion |
26 | | - ), |
27 | | - }; |
| 23 | + ); |
| 24 | + |
| 25 | + return { |
| 26 | + readme, |
| 27 | + }; |
| 28 | + } catch (error) { |
| 29 | + handleLoaderError(error, { |
| 30 | + mappings: [ |
| 31 | + createNotFoundMapping( |
| 32 | + "Readme not available.", |
| 33 | + "We could not find a readme for this package version." |
| 34 | + ), |
| 35 | + ], |
| 36 | + }); |
| 37 | + } |
28 | 38 | } |
29 | | - return { |
30 | | - status: "error", |
31 | | - message: "Failed to load readme", |
32 | | - readme: { html: "" }, |
33 | | - }; |
| 39 | + throwUserFacingPayloadResponse({ |
| 40 | + headline: "Readme not available.", |
| 41 | + description: "We could not find a readme for this package version.", |
| 42 | + category: "not_found", |
| 43 | + status: 404, |
| 44 | + }); |
34 | 45 | } |
35 | 46 |
|
36 | | -export async function clientLoader({ params }: LoaderFunctionArgs) { |
| 47 | +export function clientLoader({ params }: LoaderFunctionArgs) { |
37 | 48 | if (params.namespaceId && params.packageId && params.packageVersion) { |
38 | | - const tools = getSessionTools(); |
39 | | - const dapper = new DapperTs(() => { |
40 | | - return { |
41 | | - apiHost: tools?.getConfig().apiHost, |
42 | | - sessionId: tools?.getConfig().sessionId, |
43 | | - }; |
44 | | - }); |
| 49 | + const { dapper } = getLoaderTools(); |
| 50 | + const readme = dapper.getPackageReadme( |
| 51 | + params.namespaceId, |
| 52 | + params.packageId, |
| 53 | + params.packageVersion |
| 54 | + ); |
| 55 | + |
45 | 56 | return { |
46 | | - readme: dapper.getPackageReadme( |
47 | | - params.namespaceId, |
48 | | - params.packageId, |
49 | | - params.packageVersion |
50 | | - ), |
| 57 | + readme, |
51 | 58 | }; |
52 | 59 | } |
53 | | - return { |
54 | | - status: "error", |
55 | | - message: "Failed to load readme", |
56 | | - readme: { html: "" }, |
57 | | - }; |
| 60 | + throwUserFacingPayloadResponse({ |
| 61 | + headline: "Readme not available.", |
| 62 | + description: "We could not find a readme for this package version.", |
| 63 | + category: "not_found", |
| 64 | + status: 404, |
| 65 | + }); |
58 | 66 | } |
59 | 67 |
|
60 | 68 | export default function PackageVersionReadme() { |
61 | | - const { status, message, readme } = useLoaderData< |
62 | | - typeof loader | typeof clientLoader |
63 | | - >(); |
| 69 | + const { readme } = useLoaderData<typeof loader | typeof clientLoader>(); |
64 | 70 |
|
65 | | - if (status === "error") return <div>{message}</div>; |
66 | 71 | return ( |
67 | 72 | <Suspense fallback={<SkeletonBox className="package-readme__skeleton" />}> |
68 | | - <Await |
69 | | - resolve={readme} |
70 | | - errorElement={<div>Error occurred while loading description</div>} |
71 | | - > |
| 73 | + <Await resolve={readme} errorElement={<NimbusAwaitErrorElement />}> |
72 | 74 | {(resolvedValue) => ( |
73 | | - <> |
74 | | - <div className="markdown-wrapper"> |
75 | | - <div |
76 | | - dangerouslySetInnerHTML={{ __html: resolvedValue.html }} |
77 | | - className="markdown" |
78 | | - /> |
79 | | - </div> |
80 | | - </> |
| 75 | + <div className="markdown-wrapper"> |
| 76 | + <div |
| 77 | + dangerouslySetInnerHTML={{ __html: resolvedValue.html }} |
| 78 | + className="markdown" |
| 79 | + /> |
| 80 | + </div> |
81 | 81 | )} |
82 | 82 | </Await> |
83 | 83 | </Suspense> |
84 | 84 | ); |
85 | 85 | } |
| 86 | + |
| 87 | +export function ErrorBoundary() { |
| 88 | + return <NimbusDefaultRouteErrorBoundary />; |
| 89 | +} |
0 commit comments