Skip to content

Commit aeff7bd

Browse files
committed
Refactor loader functions to improve error handling and simplify response structure in package source tab
1 parent cd40580 commit aeff7bd

File tree

1 file changed

+47
-96
lines changed

1 file changed

+47
-96
lines changed

apps/cyberstorm-remix/app/p/tabs/Source/Source.tsx

Lines changed: 47 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -15,132 +15,79 @@ import {
1515
} from "@thunderstore/cyberstorm";
1616
import { TooltipWrapper } from "@thunderstore/cyberstorm/src/primitiveComponents/utils/utils";
1717
import { type OutletContextShape } from "~/root";
18-
import {
19-
getPublicEnvVariables,
20-
getSessionTools,
21-
} from "cyberstorm/security/publicEnvVariables";
22-
import { DapperTs } from "@thunderstore/dapper-ts";
2318
import { Alert } from "@thunderstore/cyberstorm/src/newComponents/Alert/Alert";
24-
import { isApiError } from "@thunderstore/thunderstore-api";
25-
import { getPackageSource } from "@thunderstore/dapper-ts/src/methods/package";
2619
import { CodeBoxHTML } from "../../../commonComponents/CodeBoxHTML/CodeBoxHTML";
20+
import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError";
21+
import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings";
22+
import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse";
23+
import {
24+
NimbusAwaitErrorElement,
25+
NimbusDefaultRouteErrorBoundary,
26+
} from "cyberstorm/utils/errors/NimbusErrorBoundary";
27+
import { getLoaderTools } from "cyberstorm/utils/getLoaderTools";
2728

2829
type PackageListingOutletContext = OutletContextShape & {
2930
packageDownloadUrl?: string;
3031
};
3132

32-
type ResultType = {
33-
status: string | null;
34-
message?: string;
35-
source?:
36-
| Awaited<ReturnType<typeof getPackageSource>>
37-
| ReturnType<typeof getPackageSource>;
38-
};
39-
4033
export async function loader({ params }: LoaderFunctionArgs) {
4134
if (params.namespaceId && params.packageId) {
42-
const publicEnvVariables = getPublicEnvVariables(["VITE_API_URL"]);
43-
const dapper = new DapperTs(() => {
44-
return {
45-
apiHost: publicEnvVariables.VITE_API_URL,
46-
sessionId: undefined,
47-
};
48-
});
49-
let result: ResultType = {
50-
status: null,
51-
source: undefined,
52-
message: undefined,
53-
};
35+
const { dapper } = getLoaderTools();
5436
try {
5537
const source = await dapper.getPackageSource(
5638
params.namespaceId,
5739
params.packageId
5840
);
59-
result = {
60-
status: null,
61-
source: source,
62-
message: undefined,
41+
42+
return {
43+
source,
6344
};
6445
} catch (error) {
65-
if (isApiError(error)) {
66-
if (error.response.status > 400) {
67-
result = {
68-
status: "error",
69-
source: undefined,
70-
message: `Failed to load source: ${error.message}`,
71-
};
72-
} else {
73-
throw error;
74-
}
75-
} else {
76-
throw error;
77-
}
46+
handleLoaderError(error, {
47+
mappings: [
48+
createNotFoundMapping(
49+
"Source not available.",
50+
"We could not find the requested package source."
51+
),
52+
],
53+
});
7854
}
79-
return result;
8055
}
81-
return {
82-
status: "error",
83-
message: "Failed to load source",
84-
source: undefined,
85-
};
56+
throwUserFacingPayloadResponse({
57+
headline: "Source not available.",
58+
description: "We could not find the requested package source.",
59+
category: "not_found",
60+
status: 404,
61+
});
8662
}
8763

88-
export async function clientLoader({ params }: LoaderFunctionArgs) {
64+
export function clientLoader({ params }: LoaderFunctionArgs) {
8965
if (params.namespaceId && params.packageId) {
90-
const tools = getSessionTools();
91-
const dapper = new DapperTs(() => {
92-
return {
93-
apiHost: tools.getConfig().apiHost,
94-
sessionId: tools.getConfig().sessionId,
95-
};
96-
});
97-
let result: ResultType = {
98-
status: null,
99-
source: undefined,
100-
message: undefined,
66+
const { dapper } = getLoaderTools();
67+
const source = dapper.getPackageSource(
68+
params.namespaceId,
69+
params.packageId
70+
);
71+
72+
return {
73+
source,
10174
};
102-
try {
103-
const source = dapper.getPackageSource(
104-
params.namespaceId,
105-
params.packageId
106-
);
107-
result = {
108-
status: null,
109-
source: source,
110-
message: undefined,
111-
};
112-
} catch (error) {
113-
result = {
114-
status: "error",
115-
source: undefined,
116-
message: "Failed to load source",
117-
};
118-
throw error;
119-
}
120-
return result;
12175
}
122-
return {
123-
status: "error",
124-
message: "Failed to load source",
125-
source: undefined,
126-
};
76+
throwUserFacingPayloadResponse({
77+
headline: "Source not available.",
78+
description: "We could not find the requested package source.",
79+
category: "not_found",
80+
status: 404,
81+
});
12782
}
12883

12984
export default function Source() {
130-
const { status, message, source } = useLoaderData<
131-
typeof loader | typeof clientLoader
132-
>();
85+
const { source } = useLoaderData<typeof loader | typeof clientLoader>();
13386
const outletContext = useOutletContext() as PackageListingOutletContext;
13487

135-
if (status === "error") {
136-
return <div>{message}</div>;
137-
}
13888
return (
13989
<Suspense fallback={<SkeletonBox className="package-source__skeleton" />}>
140-
<Await
141-
resolve={source}
142-
errorElement={<div>Error occurred while loading source</div>}
143-
>
90+
<Await resolve={source} errorElement={<NimbusAwaitErrorElement />}>
14491
{(resolvedValue) => {
14592
const decompilations = resolvedValue?.decompilations ?? [];
14693
const lastDecompilationDate = resolvedValue?.last_decompilation_date;
@@ -192,6 +139,10 @@ export default function Source() {
192139
);
193140
}
194141

142+
export function ErrorBoundary() {
143+
return <NimbusDefaultRouteErrorBoundary />;
144+
}
145+
195146
const DecompilationDateDisplay = (props: {
196147
lastDecompilationDate: string | null | undefined;
197148
}) => {

0 commit comments

Comments
 (0)