From 66b4bce52585fffad3e7ee7d17051c48fc9bb97e Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Fri, 30 Jun 2023 16:21:40 -0300 Subject: [PATCH 1/3] fix(App.tsx): prevent duplicate alerts from being added to the alertsList fix(alertContext.tsx): set the error, notice, and success data states before opening the respective alerts feat(chatModal/index.tsx): add error handling for websocket connection and check backend health before reconnecting --- src/frontend/src/App.tsx | 11 +++++++++- src/frontend/src/contexts/alertContext.tsx | 13 ++++++------ src/frontend/src/modals/chatModal/index.tsx | 23 +++++++++++---------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 259c40fad..3ef728925 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -51,6 +51,9 @@ export default function App() { useEffect(() => { // If there is an error alert open with data, add it to the alertsList if (errorOpen && errorData) { + if(alertsList.length > 0 && JSON.stringify(alertsList[alertsList.length - 1].data)===JSON.stringify(errorData)){ + return; + } setErrorOpen(false); setAlertsList((old) => { let newAlertsList = [ @@ -62,6 +65,9 @@ export default function App() { } // If there is a notice alert open with data, add it to the alertsList else if (noticeOpen && noticeData) { + if(alertsList.length > 0 && JSON.stringify(alertsList[alertsList.length - 1].data)===JSON.stringify(noticeData)){ + return; + } setNoticeOpen(false); setAlertsList((old) => { let newAlertsList = [ @@ -73,6 +79,9 @@ export default function App() { } // If there is a success alert open with data, add it to the alertsList else if (successOpen && successData) { + if(alertsList.length > 0 && JSON.stringify(alertsList[alertsList.length - 1].data)===JSON.stringify(successData)){ + return; + } setSuccessOpen(false); setAlertsList((old) => { let newAlertsList = [ @@ -152,4 +161,4 @@ export default function App() { ); -} +} \ No newline at end of file diff --git a/src/frontend/src/contexts/alertContext.tsx b/src/frontend/src/contexts/alertContext.tsx index ed31c03a9..62ae2e396 100644 --- a/src/frontend/src/contexts/alertContext.tsx +++ b/src/frontend/src/contexts/alertContext.tsx @@ -78,9 +78,9 @@ export function AlertProvider({ children }: { children: ReactNode }) { * @param newState An object containing the new error data, including title and optional list of error messages */ function setErrorData(newState: { title: string; list?: Array }) { - setErrorDataState(newState); - setErrorOpen(true); if (newState.title && newState.title !== "") { + setErrorDataState(newState); + setErrorOpen(true); setNotificationCenter(true); pushNotificationList({ type: "error", @@ -95,9 +95,9 @@ export function AlertProvider({ children }: { children: ReactNode }) { * @param newState An object containing the title of the notice and optionally a link. */ function setNoticeData(newState: { title: string; link?: string }) { - setNoticeDataState(newState); - setNoticeOpen(true); if (newState.title && newState.title !== "") { + setNoticeDataState(newState); + setNoticeOpen(true); // Add new notice to notification center setNotificationCenter(true); pushNotificationList({ @@ -113,11 +113,10 @@ export function AlertProvider({ children }: { children: ReactNode }) { * @param newState - A state object with a "title" property to set in the success data state. */ function setSuccessData(newState: { title: string }) { - setSuccessDataState(newState); // update the success data state with the provided new state - setSuccessOpen(true); // open the success alert - // If the new state has a "title" property, add a new success notification to the list if (newState.title && newState.title !== "") { + setSuccessDataState(newState); // update the success data state with the provided new state + setSuccessOpen(true); // open the success alert setNotificationCenter(true); // show the notification center pushNotificationList({ // add the new notification to the list diff --git a/src/frontend/src/modals/chatModal/index.tsx b/src/frontend/src/modals/chatModal/index.tsx index 6b1744857..c39ea0294 100644 --- a/src/frontend/src/modals/chatModal/index.tsx +++ b/src/frontend/src/modals/chatModal/index.tsx @@ -11,6 +11,7 @@ import { ChatMessageType } from "../../types/chat"; import ChatInput from "./chatInput"; import _ from "lodash"; +import { getHealth } from "../../controllers/API"; export default function ChatModal({ flow, @@ -204,25 +205,25 @@ export default function ChatModal({ handleOnClose(event); }; newWs.onerror = (ev) => { - console.log(ev, "error"); - if (flow.id === "") { - connectWS(); - } else { + getHealth().then((res) => { + if (res.status === 200) { + connectWS(); + } + }).catch((err) => { setErrorData({ - title: "There was an error on web connection, please: ", + // message when the backend failed + title: "The backend is not responding. Please try again later.", + // possible solution list list: [ - "Refresh the page", - "Use a new flow tab", - "Check if the backend is up", + "Check your internet connection.", + "Check if the backend is running." ], }); - } + }) }; ws.current = newWs; } catch (error) { - if (flow.id === "") { connectWS(); - } console.log(error); } } From d46aeb2efa03418c62e826da4ead6a01ffcde4ea Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Fri, 30 Jun 2023 16:27:45 -0300 Subject: [PATCH 2/3] fix(chat.py): accept websocket connection before closing it with an error code and reason --- src/backend/langflow/api/v1/chat.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index 25be65dbb..500e1d0bc 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -19,8 +19,9 @@ async def chat(client_id: str, websocket: WebSocket): if client_id in chat_manager.in_memory_cache: await chat_manager.handle_websocket(client_id, websocket) else: + await websocket.accept() message = "Please, build the flow before sending messages" - await websocket.close(code=status.WS_1008_POLICY_VIOLATION, reason=message) + await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=message) except WebSocketException as exc: logger.error(exc) await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) From e9b44ac781a54a8cb9fc34f35cc6bf40009117f3 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Fri, 30 Jun 2023 16:42:33 -0300 Subject: [PATCH 3/3] fix(chat.py): add comment explaining the behavior of accepting and immediately closing the connection if the flow is not built yet --- src/backend/langflow/api/v1/chat.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index 500e1d0bc..bf1b52058 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -19,6 +19,8 @@ async def chat(client_id: str, websocket: WebSocket): if client_id in chat_manager.in_memory_cache: await chat_manager.handle_websocket(client_id, websocket) else: + # We accept the connection but close it immediately + # if the flow is not built yet await websocket.accept() message = "Please, build the flow before sending messages" await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=message)