Skip to content

Commit

Permalink
feat: Better error message handling (All-Hands-AI#6502)
Browse files Browse the repository at this point in the history
  • Loading branch information
amanape authored and Kevin Chen committed Feb 4, 2025
1 parent 343d16b commit d5dc0a0
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 7 deletions.
6 changes: 3 additions & 3 deletions frontend/src/query-client-config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { QueryClientConfig, QueryCache } from "@tanstack/react-query";
import toast from "react-hot-toast";
import { renderToastIfError } from "./utils/render-toast-if-error";

const QUERY_KEYS_TO_IGNORE = ["authenticated", "hosts"];

export const queryClientConfig: QueryClientConfig = {
queryCache: new QueryCache({
onError: (error, query) => {
if (!QUERY_KEYS_TO_IGNORE.some((key) => query.queryKey.includes(key))) {
toast.error(error.message);
renderToastIfError(error);
}
},
}),
Expand All @@ -18,7 +18,7 @@ export const queryClientConfig: QueryClientConfig = {
},
mutations: {
onError: (error) => {
toast.error(error.message);
renderToastIfError(error);
},
},
},
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/types/react-query.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import "@tanstack/react-query";
import type { AxiosError } from "axios";

declare module "@tanstack/react-query" {
interface Register {
defaultError: AxiosError;
}
}
19 changes: 19 additions & 0 deletions frontend/src/utils/render-toast-if-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { AxiosError } from "axios";
import toast from "react-hot-toast";
import { isAxiosErrorWithResponse } from "./type-guards";

/**
* Renders a toast with the error message from an Axios error
* @param error The error to render a toast for
*/
export const renderToastIfError = (error: AxiosError) => {
let errorMessage: string | null = null;

if (isAxiosErrorWithResponse(error) && error.response?.data.error) {
errorMessage = error.response?.data.error;
} else {
errorMessage = error.message;
}

toast.error(errorMessage || "An error occurred");
};
9 changes: 9 additions & 0 deletions frontend/src/utils/type-guards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { AxiosError } from "axios";

export const isAxiosErrorWithResponse = (
error: AxiosError,
): error is AxiosError<{ error: string }> =>
typeof error.response?.data === "object" &&
error.response?.data !== null &&
"error" in error.response.data &&
typeof error.response?.data?.error === "string";
10 changes: 6 additions & 4 deletions openhands/server/routes/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ async def store_settings(
logger.warning(f'Invalid GitHub token: {e}')
return JSONResponse(
status_code=status.HTTP_401_UNAUTHORIZED,
content={'error': 'Invalid GitHub token'},
content={
'error': 'Invalid GitHub token. Please make sure it is valid.'
},
)

try:
Expand Down Expand Up @@ -102,10 +104,10 @@ async def store_settings(
await settings_store.store(settings)
return response
except Exception as e:
logger.warning(f'Invalid token: {e}')
logger.warning(f'Something went wrong storing settings: {e}')
return JSONResponse(
status_code=status.HTTP_401_UNAUTHORIZED,
content={'error': 'Invalid token'},
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content={'error': 'Something went wrong storing settings'},
)


Expand Down

0 comments on commit d5dc0a0

Please sign in to comment.