Skip to content

Commit

Permalink
feat: add generic error toasts for requests
Browse files Browse the repository at this point in the history
Signed-off-by: tylerslaton <[email protected]>
  • Loading branch information
tylerslaton committed Oct 15, 2024
1 parent a44ea9d commit 07bda29
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 7 deletions.
28 changes: 28 additions & 0 deletions ui/admin/app/components/ui/sonner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useTheme } from "next-themes";
import { Toaster as Sonner } from "sonner";

type ToasterProps = React.ComponentProps<typeof Sonner>;

const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme();

return (
<Sonner
theme={theme as ToasterProps["theme"]}
className="toaster group"
toastOptions={{
classNames: {
toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
description: "group-[.toast]:text-muted-foreground",
actionButton:
"group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
cancelButton:
"group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
},
}}
{...props}
/>
);
};

export { Toaster };
47 changes: 40 additions & 7 deletions ui/admin/app/lib/service/api/primitives.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// TODO: Add default configurations with auth tokens, etc. When ready
import axios from "axios";
import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
import { toast } from "sonner";

export const ResponseHeaders = {
RunId: "x-otto-run-id",
Expand All @@ -8,9 +9,41 @@ export const ResponseHeaders = {

const internalFetch = axios.request;

export const request: typeof internalFetch = (config) => {
return internalFetch({
adapter: "fetch",
...config,
});
};
interface ExtendedAxiosRequestConfig<D = unknown> extends AxiosRequestConfig<D> {
throwErrors?: boolean;
errorMessage?: string;
}

export async function request<T, R = AxiosResponse<T>, D = unknown>({
throwErrors = true,
errorMessage = "Request failed",
...config
}: ExtendedAxiosRequestConfig<D>): Promise<R> {
try {
return await internalFetch<T, R, D>({
adapter: "fetch",
...config,
});
} catch (error) {
handleRequestError(error, errorMessage);

if (throwErrors) {
throw error;
}
return error as R;
}
}

function handleRequestError(error: unknown, errorMessage: string): void {
if (axios.isAxiosError(error) && error.response) {
const { status, config } = error.response;
const method = config.method?.toUpperCase() || 'UNKNOWN';
toast.error(`${status} ${method}`, {
description: errorMessage,
});
} else {
toast.error("Request Error", {
description: errorMessage,
});
}
}
2 changes: 2 additions & 0 deletions ui/admin/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

import { LayoutProvider } from "~/components/layout/LayoutProvider";
import { ThemeProvider } from "~/components/theme";
import { Toaster } from "~/components/ui/sonner";

import "./tailwind.css";

Expand Down Expand Up @@ -39,6 +40,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
</head>
<body>
{children}
<Toaster closeButton />
<ScrollRestoration />
<Scripts />
</body>
Expand Down
22 changes: 22 additions & 0 deletions ui/admin/package-lock.json

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

2 changes: 2 additions & 0 deletions ui/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"date-fns": "^4.1.0",
"isbot": "^4",
"lucide-react": "^0.441.0",
"next-themes": "^0.3.0",
"query-string": "^9.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -48,6 +49,7 @@
"rehype-external-links": "^3.0.0",
"remark-gfm": "^4.0.0",
"remix-routes": "^1.7.7",
"sonner": "1.4.3",
"swr": "^2.2.5",
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7",
Expand Down

0 comments on commit 07bda29

Please sign in to comment.