Skip to content

Commit cd15356

Browse files
committed
Refactor loader functions to enhance error handling and move to different file
1 parent 62e58d0 commit cd15356

File tree

2 files changed

+69
-52
lines changed

2 files changed

+69
-52
lines changed
Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1 @@
1-
import { getSessionTools } from "cyberstorm/security/publicEnvVariables";
2-
import { type LoaderFunctionArgs } from "react-router";
3-
4-
import { DapperTs } from "@thunderstore/dapper-ts";
5-
import { ApiError, type GenericApiError } from "@thunderstore/thunderstore-api";
6-
7-
/**
8-
* TODO
9-
* 1) This approach no longer handles different ApiErrors properly
10-
* when the data isn't awaited in the clientLoader but returned as
11-
* promises for the Suspense/Await elements to handle. Instead, any
12-
* HTTP error codes are shown as 500 errors. This isn't fixed yet
13-
* as it will be easier to do once upcoming project wide error
14-
* handling changes are merged.
15-
* 2) The purpose of this helper was to reduce boilerplate in different
16-
* tab components of the team settings page. Half of that boilerplate
17-
* is Dapper setup, the other is handling ApiErrors. As the latter is
18-
* supposed to be handled elsewhere after the changes mentioned above,
19-
* this helper might no longer have a valid reason to exist after the
20-
* changes.
21-
*/
22-
export function makeTeamSettingsTabLoader<T>(
23-
dataFetcher: (dapper: DapperTs, teamName: string) => Promise<T>
24-
) {
25-
return async function clientLoader({ params }: LoaderFunctionArgs) {
26-
const teamName = params.namespaceId!;
27-
28-
try {
29-
const dapper = setupDapper();
30-
const data = await dataFetcher(dapper, teamName);
31-
return { teamName, ...data };
32-
} catch (error) {
33-
if (error instanceof ApiError) {
34-
const status = error.response.status;
35-
const statusText =
36-
(error.responseJson as GenericApiError)?.detail ??
37-
error.response.statusText;
38-
throw new Response(statusText, { status, statusText });
39-
}
40-
throw error;
41-
}
42-
};
43-
}
44-
45-
const setupDapper = () => {
46-
const tools = getSessionTools();
47-
const config = tools?.getConfig();
48-
return new DapperTs(() => ({
49-
apiHost: config?.apiHost,
50-
sessionId: config?.sessionId,
51-
}));
52-
};
1+
export { makeTeamSettingsTabLoader } from "cyberstorm/utils/getLoaderTools";
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import {
2+
getPublicEnvVariables,
3+
getSessionTools,
4+
} from "cyberstorm/security/publicEnvVariables";
5+
import type { LoaderFunctionArgs } from "react-router";
6+
7+
import { DapperTs } from "@thunderstore/dapper-ts";
8+
9+
import {
10+
ApiError,
11+
type GenericApiError,
12+
} from "../../../../packages/thunderstore-api/src";
13+
import { throwUserFacingPayloadResponse } from "./errors/userFacingErrorResponse";
14+
15+
export function getLoaderTools() {
16+
let dapper: DapperTs;
17+
let sessionTools: ReturnType<typeof getSessionTools> | undefined;
18+
if (import.meta.env.SSR) {
19+
const publicEnvVariables = getPublicEnvVariables(["VITE_API_URL"]);
20+
dapper = new DapperTs(() => {
21+
return {
22+
apiHost: publicEnvVariables.VITE_API_URL,
23+
sessionId: undefined,
24+
};
25+
});
26+
} else {
27+
sessionTools = getSessionTools();
28+
const sessionConfig = sessionTools?.getConfig();
29+
dapper = new DapperTs(() => {
30+
return {
31+
apiHost: sessionConfig?.apiHost,
32+
sessionId: sessionConfig?.sessionId,
33+
};
34+
});
35+
}
36+
return { dapper, sessionTools };
37+
}
38+
39+
export function makeTeamSettingsTabLoader<T>(
40+
dataFetcher: (dapper: DapperTs, teamName: string) => Promise<T>
41+
) {
42+
return async function clientLoader({ params }: LoaderFunctionArgs) {
43+
const teamName = params.namespaceId;
44+
if (!teamName) {
45+
throwUserFacingPayloadResponse({
46+
headline: "Team not found.",
47+
description: "We could not find the requested team.",
48+
category: "not_found",
49+
status: 404,
50+
});
51+
}
52+
53+
try {
54+
const { dapper } = getLoaderTools();
55+
const data = await dataFetcher(dapper, teamName);
56+
return { teamName, ...data };
57+
} catch (error) {
58+
if (error instanceof ApiError) {
59+
const status = error.response.status;
60+
const statusText =
61+
(error.responseJson as GenericApiError)?.detail ??
62+
error.response.statusText;
63+
throw new Response(statusText, { status, statusText });
64+
}
65+
throw error;
66+
}
67+
};
68+
}

0 commit comments

Comments
 (0)