Skip to content

Commit

Permalink
Improve error handling in the UI
Browse files Browse the repository at this point in the history
Signed-off-by: Damian Stasik <[email protected]>
  • Loading branch information
damianstasik committed Aug 28, 2024
1 parent 98ab07c commit 4f52208
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 93 deletions.
13 changes: 13 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
"eslint-plugin-react-refresh": "^0.4.11",
"globals": "^15.9.0",
"ky": "^1.7.1",
"lunr": "^2.3.9",
"openapi-typescript": "^5.4.2",
"postcss": "^8.4.41",
Expand Down
9 changes: 3 additions & 6 deletions frontend/src/q.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { queryOptions } from "@tanstack/react-query";
import lunr from "lunr";
import { api } from "./query";

export const getSearchIndexQuery = () =>
queryOptions({
queryKey: ["search-index"],
queryFn: async () => {
const response = await fetch(
`${import.meta.env.VITE_DATA_API_URL}/search.json`,
);
const data = await api(`search.json`).json();

const res = await response.json();

return lunr.Index.load(res);
return lunr.Index.load(data);
},
});
3 changes: 3 additions & 0 deletions frontend/src/query.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { QueryClient } from "@tanstack/react-query";
import ky from "ky";

export const queryClient = new QueryClient({
defaultOptions: {
Expand All @@ -7,3 +8,5 @@ export const queryClient = new QueryClient({
},
},
});

export const api = ky.create({ prefixUrl: import.meta.env.VITE_DATA_API_URL });
24 changes: 11 additions & 13 deletions frontend/src/routes/Error/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { useRouteError } from "react-router-dom";
import { Header } from "../../components/Header";
import { Paragraph } from "../../components/Paragraph";
import PatternBg from "../../components/PatternBg";
import { NotFoundPageError } from "@/utils/errors";
import { Header } from "@/components/Header";
import { Paragraph } from "@/components/Paragraph";
import PatternBg from "@/components/PatternBg";
import { is404Error } from "@/utils/errors";

export function Error() {
const routeError = useRouteError() as Error;

const title =
routeError instanceof NotFoundPageError
? "Page Not Found"
: "An Error Occurred";
const is404 = is404Error(routeError);

const message =
routeError instanceof NotFoundPageError
? "The page you are looking for does not exist."
: "We're sorry, but an unexpected error occurred. Please try again later.";
const title = is404 ? "Page Not Found" : "An Error Occurred";

const message = is404
? "The page you are looking for does not exist."
: "We're sorry, but an unexpected error occurred. Please try again later.";

return (
<>
Expand All @@ -24,7 +22,7 @@ export function Error() {
<main className="container m-auto flex flex-col items-center gap-8 text-center">
<h2 className="text-6xl font-bold">{title}</h2>
<Paragraph className="text-balance">{message}</Paragraph>
{!!routeError.message && (
{import.meta.env.DEV && !!routeError.message && (
<pre className="text-balance">{routeError.message}</pre>
)}
</main>
Expand Down
29 changes: 13 additions & 16 deletions frontend/src/routes/Module/query.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { definitions } from "@/api";
import { api } from "@/query";
import { queryOptions } from "@tanstack/react-query";

export const getModuleVersionDataQuery = (
Expand All @@ -10,13 +11,11 @@ export const getModuleVersionDataQuery = (
return queryOptions({
queryKey: ["module-version", namespace, name, target, version],
queryFn: async () => {
const response = await fetch(
`${import.meta.env.VITE_DATA_API_URL}/modules/${namespace}/${name}/${target}/${version}/index.json`,
);
const data = await api(
`modules/${namespace}/${name}/${target}/${version}/index.json`,
).json<definitions["ModuleVersion"]>();

const data = await response.json();

return data as definitions["ModuleVersion"];
return data;
},
});
};
Expand All @@ -29,13 +28,11 @@ export const getModuleDataQuery = (
return queryOptions({
queryKey: ["module", namespace, name, target],
queryFn: async () => {
const response = await fetch(
`${import.meta.env.VITE_DATA_API_URL}/modules/${namespace}/${name}/${target}/index.json`,
);

const data = await response.json();
const data = await api(
`modules/${namespace}/${name}/${target}/index.json`,
).json<definitions["Module"]>();

return data as definitions["Module"];
return data;
},
});
};
Expand All @@ -49,11 +46,11 @@ export const getModuleReadmeQuery = (
return queryOptions({
queryKey: ["module-readme", namespace, name, target, version],
queryFn: async () => {
const response = await fetch(
`${import.meta.env.VITE_DATA_API_URL}/modules/${namespace}/${name}/${target}/${version}/README.md`,
);
const data = await api(
`modules/${namespace}/${name}/${target}/${version}/README.md`,
).text();

return response.text();
return data;
},
});
};
10 changes: 5 additions & 5 deletions frontend/src/routes/ModuleExample/query.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { queryClient } from "@/query";
import { api, queryClient } from "@/query";
import { queryOptions } from "@tanstack/react-query";
import { getModuleVersionDataQuery } from "../Module/query";
import { NotFoundPageError } from "@/utils/errors";
Expand All @@ -20,11 +20,11 @@ export const getModuleExampleReadmeQuery = (
example,
],
queryFn: async () => {
const response = await fetch(
`${import.meta.env.VITE_DATA_API_URL}/modules/${namespace}/${name}/${target}/${version}/examples/${example}/README.md`,
);
const data = await api(
`modules/${namespace}/${name}/${target}/${version}/examples/${example}/README.md`,
).text();

return response.text();
return data;
},
});
};
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/routes/ModuleSubmodule/query.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { queryClient } from "@/query";
import { api, queryClient } from "@/query";
import { queryOptions } from "@tanstack/react-query";
import { getModuleVersionDataQuery } from "../Module/query";
import { NotFoundPageError } from "@/utils/errors";
Expand All @@ -20,11 +20,11 @@ export const getModuleSubmoduleReadmeQuery = (
submodule,
],
queryFn: async () => {
const response = await fetch(
`${import.meta.env.VITE_DATA_API_URL}/modules/${namespace}/${name}/${target}/${version}/modules/${submodule}/README.md`,
);
const data = await api(
`modules/${namespace}/${name}/${target}/${version}/modules/${submodule}/README.md`,
).text();

return response.text();
return data;
},
});
};
Expand Down
10 changes: 4 additions & 6 deletions frontend/src/routes/Modules/query.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { queryOptions } from "@tanstack/react-query";
import { definitions } from "@/api";
import { api } from "@/query";

export const getModulesQuery = () =>
queryOptions({
queryKey: ["modules"],
queryFn: async () => {
const response = await fetch(
`${import.meta.env.VITE_DATA_API_URL}/modules/index.json`,
);
const data =
await api(`modules/index.json`).json<definitions["ModuleList"]>();

const res = await response.json();

return res.modules as definitions["ModuleList"]["modules"];
return data.modules;
},
});
58 changes: 22 additions & 36 deletions frontend/src/routes/Provider/query.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
import { definitions } from "@/api";
import { queryOptions, skipToken } from "@tanstack/react-query";
import { api } from "@/query";
import { queryOptions } from "@tanstack/react-query";

export const getProviderVersionDataQuery = (
namespace: string | undefined,
provider: string | undefined,
version: string | undefined,
) => {
const hasParams = namespace && provider && version;

return queryOptions({
queryKey: ["provider-version", namespace, provider, version],
queryFn: hasParams
? async () => {
const response = await fetch(
`${import.meta.env.VITE_DATA_API_URL}/providers/${namespace}/${provider}/${version}/index.json`,
);

const data = await response.json();
queryFn: async () => {
const data = await api(
`providers/${namespace}/${provider}/${version}/index.json`,
).json<definitions["ProviderVersion"]>();

return data as definitions["ProviderVersion"];
}
: skipToken,
return data;
},
});
};

Expand All @@ -35,18 +30,14 @@ export const getProviderDocsQuery = (
return queryOptions({
queryKey: ["provider-doc", namespace, provider, type, name, lang, version],
queryFn: async () => {
try {
const urlBase = `${import.meta.env.VITE_DATA_API_URL}/providers/${namespace}/${provider}/${version}`;
const requestURL =
type === undefined && name === undefined
? `${urlBase}/index.md`
: `${urlBase}/${lang ? `cdktf/${lang}/` : ""}${type}/${name}.md`;

const response = await fetch(requestURL);
return response.text();
} catch {
return "";
}
const urlBase = `providers/${namespace}/${provider}/${version}`;
const requestURL =
type === undefined && name === undefined
? `${urlBase}/index.md`
: `${urlBase}/${lang ? `cdktf/${lang}/` : ""}${type}/${name}.md`;

const response = await api(requestURL).text();
return response;
},
});
};
Expand All @@ -57,17 +48,12 @@ export const getProviderDataQuery = (
) => {
return queryOptions({
queryKey: ["provider", namespace, provider],
queryFn:
namespace && provider
? async () => {
const response = await fetch(
`${import.meta.env.VITE_DATA_API_URL}/providers/${namespace}/${provider}/index.json`,
);

const data = await response.json();
queryFn: async () => {
const data = await api(
`providers/${namespace}/${provider}/index.json`,
).json<definitions["Provider"]>();

return data as definitions["Provider"];
}
: skipToken,
return data;
},
});
};
10 changes: 4 additions & 6 deletions frontend/src/routes/Providers/query.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { queryOptions } from "@tanstack/react-query";
import { definitions } from "@/api";
import { api } from "@/query";

export const getProvidersQuery = () =>
queryOptions({
queryKey: ["providers"],
queryFn: async () => {
const response = await fetch(
`${import.meta.env.VITE_DATA_API_URL}/providers/index.json`,
);
const data =
await api(`providers/index.json`).json<definitions["ProviderList"]>();

const res = await response.json();

return res.providers as definitions["ProviderList"]["providers"];
return data.providers;
},
});
9 changes: 9 additions & 0 deletions frontend/src/utils/errors.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
import { HTTPError } from "ky";

export class NotFoundPageError extends Error {}

export function is404Error(error: unknown) {
return (
error instanceof NotFoundPageError ||
(error instanceof HTTPError && error.response.status === 404)
);
}

0 comments on commit 4f52208

Please sign in to comment.