From e5bbec24a61047b65a0158e87f331fec63202dab Mon Sep 17 00:00:00 2001 From: steven Date: Wed, 29 Mar 2023 16:37:29 +0800 Subject: [PATCH] chore: update request error message --- components/ChatView/index.tsx | 16 ++++++++++------ components/CreateConnectionModal.tsx | 27 +++++++++++++++++++++------ components/QueryDrawer.tsx | 12 +++++++++--- pages/api/connection/db_schema.ts | 9 ++++++--- pages/api/connection/execute.ts | 11 ++++++++--- pages/api/connection/test.ts | 7 +++++-- store/connection.ts | 16 ++++++---------- types/api.ts | 5 +++++ types/index.ts | 1 + 9 files changed, 71 insertions(+), 33 deletions(-) create mode 100644 types/api.ts diff --git a/components/ChatView/index.tsx b/components/ChatView/index.tsx index 94983cb..5c61400 100644 --- a/components/ChatView/index.tsx +++ b/components/ChatView/index.tsx @@ -93,15 +93,19 @@ const ChatView = () => { let prompt = ""; let tokens = 0; if (connectionStore.currentConnectionCtx?.database) { - const tables = await connectionStore.getOrFetchDatabaseSchema(connectionStore.currentConnectionCtx?.database); - const promptGenerator = getPromptGeneratorOfAssistant(getAssistantById(currentChat.assistantId)!); let schema = ""; - for (const table of tables) { - if (tokens < MAX_TOKENS / 2) { - tokens += countTextTokens(schema + table.structure); - schema += table.structure; + try { + const tables = await connectionStore.getOrFetchDatabaseSchema(connectionStore.currentConnectionCtx?.database); + for (const table of tables) { + if (tokens < MAX_TOKENS / 2) { + tokens += countTextTokens(schema + table.structure); + schema += table.structure; + } } + } catch (error: any) { + toast.error(error.message); } + const promptGenerator = getPromptGeneratorOfAssistant(getAssistantById(currentChat.assistantId)!); prompt = promptGenerator(schema); } let formatedMessageList = []; diff --git a/components/CreateConnectionModal.tsx b/components/CreateConnectionModal.tsx index 4271244..35367d3 100644 --- a/components/CreateConnectionModal.tsx +++ b/components/CreateConnectionModal.tsx @@ -2,8 +2,8 @@ import { cloneDeep, head } from "lodash-es"; import { useEffect, useState } from "react"; import { createPortal } from "react-dom"; import { toast } from "react-hot-toast"; -import { testConnection, useConnectionStore } from "@/store"; -import { Connection, Engine } from "@/types"; +import { useConnectionStore } from "@/store"; +import { Connection, Engine, ResponseObject } from "@/types"; import Icon from "./Icon"; import DataStorageBanner from "./DataStorageBanner"; import ActionConfirmModal from "./ActionConfirmModal"; @@ -32,6 +32,7 @@ const CreateConnectionModal = (props: Props) => { const [isRequesting, setIsRequesting] = useState(false); const showDatabaseField = connection.engineType === Engine.PostgreSQL; const isEditing = editConnection !== undefined; + const allowSave = connection.host !== "" && connection.username !== ""; useEffect(() => { if (show) { @@ -60,11 +61,25 @@ const CreateConnectionModal = (props: Props) => { } try { - await testConnection(tempConnection); + const response = await fetch("/api/connection/test", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + connection: tempConnection, + }), + }); + const result = (await response.json()) as ResponseObject; + if (result.message) { + toast.error(result.message); + return; + } } catch (error) { + console.error(error); + toast.error("Failed to test connection"); + } finally { setIsRequesting(false); - toast.error("Failed to test connection, please check your connection configuration"); - return; } try { @@ -187,7 +202,7 @@ const CreateConnectionModal = (props: Props) => { - diff --git a/components/QueryDrawer.tsx b/components/QueryDrawer.tsx index 98d2aca..2edbbb4 100644 --- a/components/QueryDrawer.tsx +++ b/components/QueryDrawer.tsx @@ -5,6 +5,7 @@ import DataTable from "react-data-table-component"; import { toast } from "react-hot-toast"; import TextareaAutosize from "react-textarea-autosize"; import { useQueryStore } from "@/store"; +import { ResponseObject } from "@/types"; import Icon from "./Icon"; import EngineIcon from "./EngineIcon"; @@ -63,12 +64,17 @@ const QueryDrawer = () => { statement, }), }); - const result = await response.json(); - setIsLoading(false); - setRawResults(result); + const result = (await response.json()) as ResponseObject; + if (result.message) { + toast.error(result.message); + } else { + setRawResults(result.data); + } } catch (error) { console.error(error); toast.error("Failed to execute statement"); + } finally { + setIsLoading(false); } }; diff --git a/pages/api/connection/db_schema.ts b/pages/api/connection/db_schema.ts index 83f373d..a801834 100644 --- a/pages/api/connection/db_schema.ts +++ b/pages/api/connection/db_schema.ts @@ -23,10 +23,13 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { structure, }); } - res.status(200).json(tableStructures); - } catch (error) { + res.status(200).json({ + data: tableStructures, + }); + } catch (error: any) { res.status(400).json({ - error: error, + message: error.message || "Failed to get database schema.", + code: error.code || "UNKNOWN", }); } }; diff --git a/pages/api/connection/execute.ts b/pages/api/connection/execute.ts index efd3c97..fb4f7b4 100644 --- a/pages/api/connection/execute.ts +++ b/pages/api/connection/execute.ts @@ -21,9 +21,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { try { const connector = newConnector(connection); const result = await connector.execute(db, statement); - res.status(200).json(result); - } catch (error) { - res.status(400).json([]); + res.status(200).json({ + data: result, + }); + } catch (error: any) { + res.status(400).json({ + message: error.message || "Failed to execute statement.", + code: error.code || "UNKNOWN", + }); } }; diff --git a/pages/api/connection/test.ts b/pages/api/connection/test.ts index e2dd750..d9ec669 100644 --- a/pages/api/connection/test.ts +++ b/pages/api/connection/test.ts @@ -15,8 +15,11 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { const connector = newConnector(connection); await connector.testConnection(); res.status(200).json({}); - } catch (error) { - res.status(400).json({}); + } catch (error: any) { + res.status(400).json({ + message: error.message || "Failed to test connection.", + code: error.code || "UNKNOWN", + }); } }; diff --git a/store/connection.ts b/store/connection.ts index ff84f61..f5e5936 100644 --- a/store/connection.ts +++ b/store/connection.ts @@ -2,7 +2,7 @@ import axios from "axios"; import { uniqBy } from "lodash-es"; import { create } from "zustand"; import { persist } from "zustand/middleware"; -import { Connection, Database, Engine, Table } from "@/types"; +import { Connection, Database, Engine, ResponseObject, Table } from "@/types"; import { generateUUID } from "@/utils"; interface ConnectionContext { @@ -92,11 +92,14 @@ export const useConnectionStore = create()( return []; } - const { data } = await axios.post("/api/connection/db_schema", { + const { data: result } = await axios.post>("/api/connection/db_schema", { connection, db: database.name, }); - return data; + if (result.message) { + throw result.message; + } + return result.data; }, getConnectionById: (connectionId: string) => { return get().connectionList.find((connection) => connection.id === connectionId); @@ -119,10 +122,3 @@ export const useConnectionStore = create()( } ) ); - -export const testConnection = async (connection: Connection) => { - const { data: result } = await axios.post("/api/connection/test", { - connection, - }); - return result; -}; diff --git a/types/api.ts b/types/api.ts new file mode 100644 index 0000000..1134778 --- /dev/null +++ b/types/api.ts @@ -0,0 +1,5 @@ +export type ResponseObject = { + data: T; + message?: string; + code?: string; +}; diff --git a/types/index.ts b/types/index.ts index d1d5b53..99fcea9 100644 --- a/types/index.ts +++ b/types/index.ts @@ -4,3 +4,4 @@ export * from "./connection"; export * from "./database"; export * from "./chat"; export * from "./message"; +export * from "./api";