mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 13:47:19 +08:00
feat: Better error message handling (#6502)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
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"];
|
||||
|
||||
@@ -7,7 +7,7 @@ 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);
|
||||
}
|
||||
},
|
||||
}),
|
||||
@@ -18,7 +18,7 @@ export const queryClientConfig: QueryClientConfig = {
|
||||
},
|
||||
mutations: {
|
||||
onError: (error) => {
|
||||
toast.error(error.message);
|
||||
renderToastIfError(error);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
8
frontend/src/types/react-query.d.ts
vendored
Normal file
8
frontend/src/types/react-query.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import "@tanstack/react-query";
|
||||
import type { AxiosError } from "axios";
|
||||
|
||||
declare module "@tanstack/react-query" {
|
||||
interface Register {
|
||||
defaultError: AxiosError;
|
||||
}
|
||||
}
|
||||
19
frontend/src/utils/render-toast-if-error.ts
Normal file
19
frontend/src/utils/render-toast-if-error.ts
Normal file
@@ -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
frontend/src/utils/type-guards.ts
Normal file
9
frontend/src/utils/type-guards.ts
Normal file
@@ -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";
|
||||
@@ -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:
|
||||
@@ -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'},
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user