diff --git a/frontend/__tests__/context/ws-client-provider.test.tsx b/frontend/__tests__/context/ws-client-provider.test.tsx index e67a0ea56d..6c3bf564b3 100644 --- a/frontend/__tests__/context/ws-client-provider.test.tsx +++ b/frontend/__tests__/context/ws-client-provider.test.tsx @@ -27,4 +27,17 @@ describe("Propagate error message", () => { type: 'error' }); }); + + it("should display error including translation id when present", () => { + const message = "We have a problem!" + const addErrorMessageSpy = vi.spyOn(ChatSlice, "addErrorMessage") + updateStatusWhenErrorMessagePresent({message, data: {msg_id: '..id..'}}) + + expect(addErrorMessageSpy).toHaveBeenCalledWith({ + message, + id: '..id..', + status_update: true, + type: 'error' + }); + }); }); diff --git a/frontend/src/context/ws-client-provider.tsx b/frontend/src/context/ws-client-provider.tsx index e061835074..11b5ca95b3 100644 --- a/frontend/src/context/ws-client-provider.tsx +++ b/frontend/src/context/ws-client-provider.tsx @@ -67,16 +67,33 @@ interface WsClientProviderProps { conversationId: string; } -export function updateStatusWhenErrorMessagePresent(data: unknown) { - if ( - data && - typeof data === "object" && - "message" in data && - typeof data.message === "string" - ) { +interface ErrorArg { + message?: string; + data?: ErrorArgData | unknown; +} + +interface ErrorArgData { + msg_id: string; +} + +export function updateStatusWhenErrorMessagePresent(data: ErrorArg | unknown) { + const isObject = (val: unknown): val is object => + !!val && typeof val === "object"; + const isString = (val: unknown): val is string => typeof val === "string"; + if (isObject(data) && "message" in data && isString(data.message)) { + let msgId: string | undefined; + if ( + "data" in data && + isObject(data.data) && + "msg_id" in data.data && + isString(data.data.msg_id) + ) { + msgId = data.data.msg_id; + } handleStatusMessage({ type: "error", message: data.message, + id: msgId, status_update: true, }); } diff --git a/frontend/src/i18n/translation.json b/frontend/src/i18n/translation.json index 167909c995..528713ead7 100644 --- a/frontend/src/i18n/translation.json +++ b/frontend/src/i18n/translation.json @@ -454,6 +454,10 @@ "fr": "Nous avons modifié certains paramètres dans la dernière mise à jour. Prenez un moment pour les examiner.", "tr": "Son güncellemede bazı ayarları değiştirdik. Gözden geçirmek için bir dakikanızı ayırın." }, + "CONFIGURATION$SETTINGS_NOT_FOUND": { + "en": "Settings not found. Please check your API key", + "es": "Configuraciones no encontradas. Por favor revisa tu API key" + }, "CONFIGURATION$AGENT_LOADING": { "en": "Please wait while the agent loads. This may take a few minutes...", "de": "Bitte warten Sie, während der Agent lädt. Das kann ein paar Minuten dauern...", diff --git a/openhands/server/listen_socket.py b/openhands/server/listen_socket.py index 4bb81aad66..884b7e3b7c 100644 --- a/openhands/server/listen_socket.py +++ b/openhands/server/listen_socket.py @@ -57,7 +57,9 @@ async def connect(connection_id: str, environ, auth): settings = await settings_store.load() if not settings: - raise ConnectionRefusedError('Settings not found') + raise ConnectionRefusedError( + 'Settings not found', {'msg_id': 'CONFIGURATION$SETTINGS_NOT_FOUND'} + ) try: event_stream = await session_manager.join_conversation(