### What problem does this PR solve? feat: catch errors when sending messages #918 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.8.0
| @@ -1,6 +1,7 @@ | |||
| import { Authorization } from '@/constants/authorization'; | |||
| import { LanguageTranslationMap } from '@/constants/common'; | |||
| import { Pagination } from '@/interfaces/common'; | |||
| import { ResponseType } from '@/interfaces/database/base'; | |||
| import { IAnswer } from '@/interfaces/database/chat'; | |||
| import { IKnowledgeFile } from '@/interfaces/database/knowledge'; | |||
| import { IChangeParserConfigRequestBody } from '@/interfaces/request/document'; | |||
| @@ -153,7 +154,9 @@ export const useSendMessageWithSse = ( | |||
| const [done, setDone] = useState(true); | |||
| const send = useCallback( | |||
| async (body: any) => { | |||
| async ( | |||
| body: any, | |||
| ): Promise<{ response: Response; data: ResponseType } | undefined> => { | |||
| try { | |||
| setDone(false); | |||
| const response = await fetch(url, { | |||
| @@ -165,6 +168,8 @@ export const useSendMessageWithSse = ( | |||
| body: JSON.stringify(body), | |||
| }); | |||
| const res = response.clone().json(); | |||
| const reader = response?.body | |||
| ?.pipeThrough(new TextDecoderStream()) | |||
| .pipeThrough(new EventSourceParserStream()) | |||
| @@ -192,7 +197,7 @@ export const useSendMessageWithSse = ( | |||
| } | |||
| console.info('done?'); | |||
| setDone(true); | |||
| return response; | |||
| return { data: await res, response }; | |||
| } catch (e) { | |||
| setDone(true); | |||
| console.warn(e); | |||
| @@ -0,0 +1,6 @@ | |||
| export interface ResponseType { | |||
| retcode: number; | |||
| data: any; | |||
| retmsg: string; | |||
| status: number; | |||
| } | |||
| @@ -19,6 +19,7 @@ import { | |||
| } from '../hooks'; | |||
| import { TextUpdaterNode } from './node'; | |||
| import ChatDrawer from '../chat/drawer'; | |||
| import styles from './index.less'; | |||
| const nodeTypes = { textUpdater: TextUpdaterNode }; | |||
| @@ -29,9 +30,11 @@ const edgeTypes = { | |||
| interface IProps { | |||
| sideWidth: number; | |||
| chatDrawerVisible: boolean; | |||
| hideChatDrawer(): void; | |||
| } | |||
| function FlowCanvas({ sideWidth }: IProps) { | |||
| function FlowCanvas({ sideWidth, chatDrawerVisible, hideChatDrawer }: IProps) { | |||
| const { | |||
| nodes, | |||
| edges, | |||
| @@ -99,6 +102,10 @@ function FlowCanvas({ sideWidth }: IProps) { | |||
| visible={drawerVisible} | |||
| hideModal={hideDrawer} | |||
| ></FlowDrawer> | |||
| <ChatDrawer | |||
| visible={chatDrawerVisible} | |||
| hideModal={hideChatDrawer} | |||
| ></ChatDrawer> | |||
| </div> | |||
| ); | |||
| } | |||
| @@ -82,6 +82,7 @@ const FlowChatBox = () => { | |||
| onClose={hideModal} | |||
| open={visible} | |||
| width={'50vw'} | |||
| mask={false} | |||
| > | |||
| <DocumentPreviewer | |||
| documentId={documentId} | |||
| @@ -11,6 +11,7 @@ const ChatDrawer = ({ visible, hideModal }: IModalProps<any>) => { | |||
| open={visible} | |||
| getContainer={false} | |||
| width={470} | |||
| mask={false} | |||
| // zIndex={10000} | |||
| > | |||
| <FlowChatBox></FlowChatBox> | |||
| @@ -8,10 +8,13 @@ import { | |||
| import { IAnswer } from '@/interfaces/database/chat'; | |||
| import { IMessage } from '@/pages/chat/interface'; | |||
| import api from '@/utils/api'; | |||
| import { message } from 'antd'; | |||
| import { useCallback, useEffect, useState } from 'react'; | |||
| import { useParams } from 'umi'; | |||
| import { v4 as uuid } from 'uuid'; | |||
| const antMessage = message; | |||
| export const useSelectCurrentMessages = () => { | |||
| const { id: id } = useParams(); | |||
| const [currentMessages, setCurrentMessages] = useState<IMessage[]>([]); | |||
| @@ -107,9 +110,11 @@ export const useSendMessage = ( | |||
| if (message) { | |||
| params.message = message; | |||
| } | |||
| const res: Response | undefined = await send(params); | |||
| const res = await send(params); | |||
| if (res?.response.status !== 200 || res?.data?.retcode !== 0) { | |||
| antMessage.error(res?.data?.retmsg); | |||
| if (res?.status !== 200) { | |||
| // cancel loading | |||
| setValue(message); | |||
| removeLatestMessage(); | |||
| @@ -1,21 +1,19 @@ | |||
| import { Button, Flex, Space } from 'antd'; | |||
| import { useSetModalState } from '@/hooks/commonHooks'; | |||
| import { useFetchFlow } from '@/hooks/flow-hooks'; | |||
| import { ArrowLeftOutlined } from '@ant-design/icons'; | |||
| import { Link } from 'umi'; | |||
| import ChatDrawer from '../chat/drawer'; | |||
| import { useRunGraph, useSaveGraph } from '../hooks'; | |||
| import { useSaveGraph } from '../hooks'; | |||
| import styles from './index.less'; | |||
| const FlowHeader = () => { | |||
| interface IProps { | |||
| showChatDrawer(): void; | |||
| } | |||
| const FlowHeader = ({ showChatDrawer }: IProps) => { | |||
| const { saveGraph } = useSaveGraph(); | |||
| const { runGraph } = useRunGraph(); | |||
| const { | |||
| visible: chatDrawerVisible, | |||
| hideModal: hideChatDrawer, | |||
| showModal: showChatDrawer, | |||
| } = useSetModalState(); | |||
| const { data } = useFetchFlow(); | |||
| return ( | |||
| @@ -41,10 +39,6 @@ const FlowHeader = () => { | |||
| </Button> | |||
| </Space> | |||
| </Flex> | |||
| <ChatDrawer | |||
| visible={chatDrawerVisible} | |||
| hideModal={hideChatDrawer} | |||
| ></ChatDrawer> | |||
| </> | |||
| ); | |||
| }; | |||
| @@ -2,7 +2,6 @@ import { useSetModalState } from '@/hooks/commonHooks'; | |||
| import { | |||
| useFetchFlow, | |||
| useFetchFlowTemplates, | |||
| useRunFlow, | |||
| useSetFlow, | |||
| } from '@/hooks/flow-hooks'; | |||
| import { useFetchLlmList } from '@/hooks/llmHooks'; | |||
| @@ -216,19 +215,3 @@ export const useFetchDataOnMount = () => { | |||
| export const useFlowIsFetching = () => { | |||
| return useIsFetching({ queryKey: ['flowDetail'] }) > 0; | |||
| }; | |||
| export const useRunGraph = () => { | |||
| const { data } = useFetchFlow(); | |||
| const { runFlow } = useRunFlow(); | |||
| const { id } = useParams(); | |||
| const { nodes, edges } = useGraphStore((state) => state); | |||
| const runGraph = useCallback(() => { | |||
| const dslComponents = buildDslComponentsByGraph(nodes, edges); | |||
| runFlow({ | |||
| id: id!!, | |||
| dsl: { ...data.dsl, components: dslComponents }, | |||
| }); | |||
| }, [nodes, edges, runFlow, id, data]); | |||
| return { runGraph }; | |||
| }; | |||
| @@ -1,3 +1,4 @@ | |||
| import { useSetModalState } from '@/hooks/commonHooks'; | |||
| import { Layout } from 'antd'; | |||
| import { useState } from 'react'; | |||
| import { ReactFlowProvider } from 'reactflow'; | |||
| @@ -10,6 +11,11 @@ const { Content } = Layout; | |||
| function RagFlow() { | |||
| const [collapsed, setCollapsed] = useState(false); | |||
| const { | |||
| visible: chatDrawerVisible, | |||
| hideModal: hideChatDrawer, | |||
| showModal: showChatDrawer, | |||
| } = useSetModalState(); | |||
| useFetchDataOnMount(); | |||
| @@ -18,9 +24,13 @@ function RagFlow() { | |||
| <ReactFlowProvider> | |||
| <Sider setCollapsed={setCollapsed} collapsed={collapsed}></Sider> | |||
| <Layout> | |||
| <FlowHeader></FlowHeader> | |||
| <FlowHeader showChatDrawer={showChatDrawer}></FlowHeader> | |||
| <Content style={{ margin: 0 }}> | |||
| <FlowCanvas sideWidth={collapsed ? 0 : 200}></FlowCanvas> | |||
| <FlowCanvas | |||
| sideWidth={collapsed ? 0 : 200} | |||
| chatDrawerVisible={chatDrawerVisible} | |||
| hideChatDrawer={hideChatDrawer} | |||
| ></FlowCanvas> | |||
| </Content> | |||
| </Layout> | |||
| </ReactFlowProvider> | |||
| @@ -1,4 +1,5 @@ | |||
| import { Authorization } from '@/constants/authorization'; | |||
| import { ResponseType } from '@/interfaces/database/base'; | |||
| import i18n from '@/locales/config'; | |||
| import authorizationUtil, { getAuthorization } from '@/utils/authorizationUtil'; | |||
| import { message, notification } from 'antd'; | |||
| @@ -42,12 +43,6 @@ type ResultCode = | |||
| | 503 | |||
| | 504; | |||
| interface ResponseType { | |||
| retcode: number; | |||
| data: any; | |||
| retmsg: string; | |||
| status: number; | |||
| } | |||
| const errorHandler = (error: { | |||
| response: Response; | |||
| message: string; | |||