Skip to content

Commit 7920110

Browse files
committed
Enhance error handling in all package versions routes
1 parent 5ac0d36 commit 7920110

File tree

3 files changed

+146
-124
lines changed

3 files changed

+146
-124
lines changed

apps/cyberstorm-remix/app/p/tabs/Versions/PackageVersionVersions.tsx

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,61 +22,62 @@ import { DownloadLink, InstallLink, ModManagerBanner } from "./common";
2222

2323
export async function loader({ params }: LoaderFunctionArgs) {
2424
if (params.communityId && params.namespaceId && params.packageId) {
25-
const publicEnvVariables = getPublicEnvVariables(["VITE_API_URL"]);
26-
const dapper = new DapperTs(() => {
25+
const { dapper } = getLoaderTools();
26+
try {
27+
const versions = await dapper.getPackageVersions(
28+
params.namespaceId,
29+
params.packageId
30+
);
31+
2732
return {
28-
apiHost: publicEnvVariables.VITE_API_URL,
29-
sessionId: undefined,
33+
communityId: params.communityId,
34+
namespaceId: params.namespaceId,
35+
packageId: params.packageId,
36+
versions,
3037
};
31-
});
32-
return {
33-
communityId: params.communityId,
34-
namespaceId: params.namespaceId,
35-
packageId: params.packageId,
36-
versions: dapper.getPackageVersions(params.namespaceId, params.packageId),
37-
};
38+
} catch (error) {
39+
handleLoaderError(error, { mappings: packageVersionsErrorMappings });
40+
}
3841
}
39-
return {
40-
status: "error",
41-
message: "Failed to load versions",
42-
versions: [],
43-
};
42+
throwUserFacingPayloadResponse({
43+
headline: "Package not found.",
44+
description: "We could not find the requested package.",
45+
category: "not_found",
46+
status: 404,
47+
});
4448
}
4549

46-
export async function clientLoader({ params }: LoaderFunctionArgs) {
50+
export function clientLoader({ params }: LoaderFunctionArgs) {
4751
if (params.communityId && params.namespaceId && params.packageId) {
48-
const tools = getSessionTools();
49-
const dapper = new DapperTs(() => {
50-
return {
51-
apiHost: tools?.getConfig().apiHost,
52-
sessionId: tools?.getConfig().sessionId,
53-
};
54-
});
52+
const { dapper } = getLoaderTools();
53+
const versions = dapper.getPackageVersions(
54+
params.namespaceId,
55+
params.packageId
56+
);
57+
5558
return {
5659
communityId: params.communityId,
5760
namespaceId: params.namespaceId,
5861
packageId: params.packageId,
59-
versions: dapper.getPackageVersions(params.namespaceId, params.packageId),
62+
versions,
6063
};
6164
}
62-
return {
63-
status: "error",
64-
message: "Failed to load versions",
65-
versions: [],
66-
};
65+
throwUserFacingPayloadResponse({
66+
headline: "Package not found.",
67+
description: "We could not find the requested package.",
68+
category: "not_found",
69+
status: 404,
70+
});
6771
}
6872

6973
export default function Versions() {
70-
const { communityId, namespaceId, packageId, status, message, versions } =
71-
useLoaderData<typeof loader | typeof clientLoader>();
72-
73-
if (status === "error") {
74-
return <div>{message}</div>;
75-
}
74+
const { communityId, namespaceId, packageId, versions } = useLoaderData<
75+
typeof loader | typeof clientLoader
76+
>();
7677

7778
return (
7879
<Suspense fallback={<SkeletonBox className="package-versions__skeleton" />}>
79-
<Await resolve={versions}>
80+
<Await resolve={versions} errorElement={<NimbusAwaitErrorElement />}>
8081
{(resolvedValue) => (
8182
<div className="package-versions">
8283
<ModManagerBanner />
@@ -134,3 +135,7 @@ export default function Versions() {
134135
</Suspense>
135136
);
136137
}
138+
139+
export function ErrorBoundary() {
140+
return <NimbusDefaultRouteErrorBoundary />;
141+
}

apps/cyberstorm-remix/app/p/tabs/Versions/PackageVersionWithoutCommunityVersions.tsx

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,60 +22,60 @@ import { DownloadLink, InstallLink, ModManagerBanner } from "./common";
2222

2323
export async function loader({ params }: LoaderFunctionArgs) {
2424
if (params.namespaceId && params.packageId) {
25-
const publicEnvVariables = getPublicEnvVariables(["VITE_API_URL"]);
26-
const dapper = new DapperTs(() => {
25+
const { dapper } = getLoaderTools();
26+
try {
27+
const versions = await dapper.getPackageVersions(
28+
params.namespaceId,
29+
params.packageId
30+
);
31+
2732
return {
28-
apiHost: publicEnvVariables.VITE_API_URL,
29-
sessionId: undefined,
33+
namespaceId: params.namespaceId,
34+
packageId: params.packageId,
35+
versions,
3036
};
31-
});
32-
return {
33-
namespaceId: params.namespaceId,
34-
packageId: params.packageId,
35-
versions: dapper.getPackageVersions(params.namespaceId, params.packageId),
36-
};
37+
} catch (error) {
38+
handleLoaderError(error, { mappings: packageVersionsErrorMappings });
39+
}
3740
}
38-
return {
39-
status: "error",
40-
message: "Failed to load versions",
41-
versions: [],
42-
};
41+
throwUserFacingPayloadResponse({
42+
headline: "Package not found.",
43+
description: "We could not find the requested package.",
44+
category: "not_found",
45+
status: 404,
46+
});
4347
}
4448

45-
export async function clientLoader({ params }: LoaderFunctionArgs) {
49+
export function clientLoader({ params }: LoaderFunctionArgs) {
4650
if (params.namespaceId && params.packageId) {
47-
const tools = getSessionTools();
48-
const dapper = new DapperTs(() => {
49-
return {
50-
apiHost: tools?.getConfig().apiHost,
51-
sessionId: tools?.getConfig().sessionId,
52-
};
53-
});
51+
const { dapper } = getLoaderTools();
52+
const versions = dapper.getPackageVersions(
53+
params.namespaceId,
54+
params.packageId
55+
);
56+
5457
return {
5558
namespaceId: params.namespaceId,
5659
packageId: params.packageId,
57-
versions: dapper.getPackageVersions(params.namespaceId, params.packageId),
60+
versions,
5861
};
5962
}
60-
return {
61-
status: "error",
62-
message: "Failed to load versions",
63-
versions: [],
64-
};
63+
throwUserFacingPayloadResponse({
64+
headline: "Package not found.",
65+
description: "We could not find the requested package.",
66+
category: "not_found",
67+
status: 404,
68+
});
6569
}
6670

6771
export default function Versions() {
68-
const { namespaceId, packageId, status, message, versions } = useLoaderData<
72+
const { namespaceId, packageId, versions } = useLoaderData<
6973
typeof loader | typeof clientLoader
7074
>();
7175

72-
if (status === "error") {
73-
return <div>{message}</div>;
74-
}
75-
7676
return (
7777
<Suspense fallback={<SkeletonBox className="package-versions__skeleton" />}>
78-
<Await resolve={versions}>
78+
<Await resolve={versions} errorElement={<NimbusAwaitErrorElement />}>
7979
{(resolvedValue) => (
8080
<div className="package-versions">
8181
<ModManagerBanner />
@@ -132,3 +132,7 @@ export default function Versions() {
132132
</Suspense>
133133
);
134134
}
135+
136+
export function ErrorBoundary() {
137+
return <NimbusDefaultRouteErrorBoundary />;
138+
}

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

Lines changed: 65 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,91 @@
1+
import "./Versions.css";
12
import {
2-
getPublicEnvVariables,
3-
getSessionTools,
4-
} from "cyberstorm/security/publicEnvVariables";
5-
import { rowSemverCompare } from "cyberstorm/utils/semverCompare";
6-
import { Suspense } from "react";
7-
import { Await, type LoaderFunctionArgs } from "react-router";
8-
import { useLoaderData } from "react-router";
9-
10-
import {
11-
Heading,
12-
NewLink,
3+
NewTableSort,
134
NewTable,
145
type NewTableLabels,
15-
NewTableSort,
6+
Heading,
167
SkeletonBox,
8+
NewLink,
179
} from "@thunderstore/cyberstorm";
18-
import { DapperTs } from "@thunderstore/dapper-ts";
19-
20-
import "./Versions.css";
10+
import { Await, type LoaderFunctionArgs } from "react-router";
11+
import { useLoaderData } from "react-router";
12+
import { Suspense } from "react";
2113
import { DownloadLink, InstallLink, ModManagerBanner } from "./common";
14+
import { rowSemverCompare } from "cyberstorm/utils/semverCompare";
15+
import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError";
16+
import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings";
17+
import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse";
18+
import {
19+
NimbusAwaitErrorElement,
20+
NimbusDefaultRouteErrorBoundary,
21+
} from "cyberstorm/utils/errors/NimbusErrorBoundary";
22+
import { getLoaderTools } from "cyberstorm/utils/getLoaderTools";
23+
24+
export const packageVersionsErrorMappings = [
25+
createNotFoundMapping(
26+
"Package not found.",
27+
"We could not find the requested package."
28+
),
29+
];
2230

2331
export async function loader({ params }: LoaderFunctionArgs) {
2432
if (params.communityId && params.namespaceId && params.packageId) {
25-
const publicEnvVariables = getPublicEnvVariables(["VITE_API_URL"]);
26-
const dapper = new DapperTs(() => {
33+
const { dapper } = getLoaderTools();
34+
try {
35+
const versions = await dapper.getPackageVersions(
36+
params.namespaceId,
37+
params.packageId
38+
);
39+
2740
return {
28-
apiHost: publicEnvVariables.VITE_API_URL,
29-
sessionId: undefined,
41+
communityId: params.communityId,
42+
namespaceId: params.namespaceId,
43+
packageId: params.packageId,
44+
versions,
3045
};
31-
});
32-
return {
33-
communityId: params.communityId,
34-
namespaceId: params.namespaceId,
35-
packageId: params.packageId,
36-
versions: dapper.getPackageVersions(params.namespaceId, params.packageId),
37-
};
46+
} catch (error) {
47+
handleLoaderError(error, { mappings: packageVersionsErrorMappings });
48+
}
3849
}
39-
return {
40-
status: "error",
41-
message: "Failed to load versions",
42-
versions: [],
43-
};
50+
throwUserFacingPayloadResponse({
51+
headline: "Package not found.",
52+
description: "We could not find the requested package.",
53+
category: "not_found",
54+
status: 404,
55+
});
4456
}
4557

46-
export async function clientLoader({ params }: LoaderFunctionArgs) {
58+
export function clientLoader({ params }: LoaderFunctionArgs) {
4759
if (params.communityId && params.namespaceId && params.packageId) {
48-
const tools = getSessionTools();
49-
const dapper = new DapperTs(() => {
50-
return {
51-
apiHost: tools?.getConfig().apiHost,
52-
sessionId: tools?.getConfig().sessionId,
53-
};
54-
});
60+
const { dapper } = getLoaderTools();
61+
const versions = dapper.getPackageVersions(
62+
params.namespaceId,
63+
params.packageId
64+
);
65+
5566
return {
5667
communityId: params.communityId,
5768
namespaceId: params.namespaceId,
5869
packageId: params.packageId,
59-
versions: dapper.getPackageVersions(params.namespaceId, params.packageId),
70+
versions,
6071
};
6172
}
62-
return {
63-
status: "error",
64-
message: "Failed to load versions",
65-
versions: [],
66-
};
73+
throwUserFacingPayloadResponse({
74+
headline: "Package not found.",
75+
description: "We could not find the requested package.",
76+
category: "not_found",
77+
status: 404,
78+
});
6779
}
6880

6981
export default function Versions() {
70-
const { communityId, namespaceId, packageId, status, message, versions } =
71-
useLoaderData<typeof loader | typeof clientLoader>();
72-
73-
if (status === "error") {
74-
return <div>{message}</div>;
75-
}
82+
const { communityId, namespaceId, packageId, versions } = useLoaderData<
83+
typeof loader | typeof clientLoader
84+
>();
7685

7786
return (
7887
<Suspense fallback={<SkeletonBox className="package-versions__skeleton" />}>
79-
<Await resolve={versions}>
88+
<Await resolve={versions} errorElement={<NimbusAwaitErrorElement />}>
8089
{(resolvedValue) => (
8190
<div className="package-versions">
8291
<ModManagerBanner />
@@ -135,6 +144,10 @@ export default function Versions() {
135144
);
136145
}
137146

147+
export function ErrorBoundary() {
148+
return <NimbusDefaultRouteErrorBoundary />;
149+
}
150+
138151
export const columns: NewTableLabels = [
139152
{
140153
value: "Version",

0 commit comments

Comments
 (0)