Skip to content

Commit 8e29d92

Browse files
committed
refactor: interceptor
1 parent 9948153 commit 8e29d92

4 files changed

Lines changed: 129 additions & 77 deletions

File tree

src/api/axios.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ import { AxiosRequestConfig } from 'axios'
44
declare module 'axios' {
55
export interface AxiosRequestConfig<D = any> {
66
traceTimeStart?: number
7+
suppressErrorToast?: boolean
78
}
89
}

src/api/editor.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,19 @@ const getTableByName = (tableName: string, database?: string) => {
9595
)
9696
}
9797

98-
const runSQL = (code: string, database?: string): Promise<HttpResponse> => {
99-
return axios.post(sqlUrl, makeSqlData(code), addDatabaseParams(database))
98+
function runSQL(code: string): Promise<HttpResponse>
99+
function runSQL(code: string, database: string, config?: AxiosRequestConfig): Promise<HttpResponse>
100+
function runSQL(code: string, database?: string, config?: AxiosRequestConfig): Promise<HttpResponse> {
101+
const baseConfig = addDatabaseParams(database)
102+
const mergedConfig = {
103+
...baseConfig,
104+
...config,
105+
params: {
106+
...baseConfig.params,
107+
...config?.params,
108+
},
109+
} as AxiosRequestConfig
110+
return axios.post(sqlUrl, makeSqlData(code), mergedConfig)
100111
}
101112

102113
const checkScriptsTable = () => {
@@ -172,7 +183,7 @@ const getTableSchema = (tableName: string, database?: string) => {
172183
),
173184
addDatabaseParams(database)
174185
)
175-
.then((res) => {
186+
.then((res: any) => {
176187
return res.output[0].records.rows.map((row: string[]) => {
177188
return {
178189
name: row[0],

src/api/interceptor.ts

Lines changed: 110 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export interface Auth {
2222

2323
// todo: can we use env and proxy at the same time?
2424
export const TableNameReg = /(?<=from|FROM)\s+([^\s;]+)/i
25+
const V1_PREFIX = '/v1'
26+
const V1_INFLUX_PREFIX = '/v1/influxdb'
2527
/**
2628
* Parse table reference from SQL after FROM. Returns the raw table reference as-is (e.g. "temp_data"."cpu_metrics"), no conversion.
2729
*/
@@ -39,9 +41,97 @@ export function parseTable(sql: string) {
3941
return parseTableFromSql(sql)
4042
}
4143

44+
const isV1Request = (url?: string) => !!url?.startsWith(V1_PREFIX)
45+
const isInfluxRequest = (url?: string) => !!url?.startsWith(V1_INFLUX_PREFIX)
46+
47+
const getStartTimestamp = (value?: Date | number) => {
48+
if (!value) return undefined
49+
const start = new Date(value).valueOf()
50+
return Number.isNaN(start) ? undefined : start
51+
}
52+
53+
const formatStartTime = (value?: Date | number) => {
54+
const start = getStartTimestamp(value)
55+
return start ? new Date(start).toLocaleTimeString() : new Date().toLocaleTimeString()
56+
}
57+
58+
const getTraceTiming = (value?: Date | number) => {
59+
const start = getStartTimestamp(value)
60+
const now = Date.now()
61+
return {
62+
networkTime: start ? now - start : 0,
63+
startTime: formatStartTime(value),
64+
}
65+
}
66+
67+
const shouldNotifyError = (config?: AxiosRequestConfig) => {
68+
if (isInfluxRequest(config?.url)) return false
69+
return !config?.suppressErrorToast
70+
}
71+
72+
const showErrorMessage = (content: string) => {
73+
Message.error({
74+
content,
75+
duration: 3 * 1000,
76+
closable: true,
77+
resetOnHover: true,
78+
})
79+
}
80+
81+
const parseV1Data = (payload: unknown) => {
82+
if (typeof payload !== 'string') return payload
83+
return JSONbigint({ storeAsString: true }).parse(payload)
84+
}
85+
86+
const buildErrorPayload = (errorMessage: string, traceTimeStart?: Date | number) => {
87+
return {
88+
error: errorMessage,
89+
startTime: formatStartTime(traceTimeStart),
90+
}
91+
}
92+
93+
const handleV1Response = (response: AxiosResponse) => {
94+
const isInflux = isInfluxRequest(response.config.url)
95+
96+
if (isInflux) {
97+
if (response.status === 204) {
98+
return getTraceTiming(response.config.traceTimeStart)
99+
}
100+
const message = response.data?.error || 'Error'
101+
return Promise.reject(buildErrorPayload(message, response.config.traceTimeStart))
102+
}
103+
104+
if (response.config.params?.format?.includes('csv')) {
105+
return response.data || []
106+
}
107+
108+
const data = parseV1Data(response.data) as HttpResponse
109+
if (data.code && data.code !== 0) {
110+
const message = data.error || 'Error'
111+
if (shouldNotifyError(response.config)) {
112+
showErrorMessage(message)
113+
}
114+
return Promise.reject(buildErrorPayload(message, response.config.traceTimeStart))
115+
}
116+
117+
return {
118+
...data,
119+
...getTraceTiming(response.config.traceTimeStart),
120+
}
121+
}
122+
123+
const parseV1ErrorData = (rawData: unknown) => {
124+
if (typeof rawData !== 'string') return rawData
125+
try {
126+
return JSON.parse(rawData)
127+
} catch {
128+
return rawData
129+
}
130+
}
131+
42132
axios.interceptors.request.use(
43133
(config: AxiosRequestConfig) => {
44-
const isV1 = !!config.url?.startsWith(`/v1`)
134+
const isV1 = isV1Request(config.url)
45135
const appStore = useAppStore()
46136

47137
if (!config.headers) {
@@ -71,91 +161,39 @@ axios.interceptors.request.use(
71161
return Promise.reject(error)
72162
}
73163
)
74-
const ignoreList = ['pipelines']
75164

76165
axios.interceptors.response.use(
77166
(response: AxiosResponse) => {
78-
const isV1 = !!response.config.url?.startsWith(`/v1`)
79-
const isInflux = !!response.config.url?.startsWith(`/v1/influxdb`)
80-
if (isInflux) {
81-
if (response.status === 204) {
82-
return {
83-
networkTime: new Date().valueOf() - response.config.traceTimeStart,
84-
startTime: new Date(response.config.traceTimeStart).toLocaleTimeString(),
85-
}
86-
}
87-
const errorResponse = {
88-
error: response.data.error || 'Error',
89-
startTime: new Date(response.config.traceTimeStart).toLocaleTimeString(),
90-
}
91-
return Promise.reject(errorResponse)
92-
}
93-
if (isV1) {
94-
if (response.config.params?.format?.includes('csv')) {
95-
return response.data || []
96-
}
97-
response.data = JSONbigint({ storeAsString: true }).parse(response.data)
98-
const { data } = response
99-
if (data.code && data.code !== 0) {
100-
// v1 and error
101-
const tableName = parseTable(response.config.data)
102-
if (ignoreList.indexOf(tableName) === -1) {
103-
Message.error({
104-
content: data.error || 'Error',
105-
duration: 3 * 1000,
106-
closable: true,
107-
resetOnHover: true,
108-
})
109-
}
110-
const error = {
111-
error: data.error || 'Error',
112-
startTime: new Date(response.config.traceTimeStart).toLocaleTimeString(),
113-
}
114-
return Promise.reject(error)
115-
}
116-
// v1 and success
117-
return {
118-
...data,
119-
networkTime: new Date().valueOf() - response.config.traceTimeStart,
120-
startTime: new Date(response.config.traceTimeStart).toLocaleTimeString(),
121-
}
122-
}
123-
const { data } = response
124-
return data
167+
if (isV1Request(response.config.url)) return handleV1Response(response)
168+
return response.data
125169
},
126170

127171
(error) => {
128-
const isV1 = !!error.config.url?.startsWith(`/v1`)
172+
const response = error?.response
173+
const config = error?.config
129174

130-
if (error.response.status === 401) {
175+
if (response?.status === 401) {
131176
const appStore = useAppStore()
132177
appStore.openGlobalSettings()
133178
}
134179

135-
if (isV1) {
136-
try {
137-
error.response.data = JSON.parse(error.response.data)
138-
} catch (e) {
139-
//
140-
}
180+
if (!response) {
181+
const message = error?.message || 'Request Error'
182+
if (shouldNotifyError(config)) showErrorMessage(message)
183+
return Promise.reject(buildErrorPayload(message, config?.traceTimeStart))
141184
}
142185

143-
const { data } = error.response
144-
145-
const isInflux = !!error.config.url?.startsWith(`/v1/influxdb`)
146-
const tableName = parseTable(error.response.config.data)
147-
if (!isInflux && ignoreList.indexOf(tableName) === -1) {
148-
Message.error({
149-
content: data.error || error.message || 'Request Error',
150-
duration: 3 * 1000,
151-
closable: true,
152-
resetOnHover: true,
153-
})
186+
if (isV1Request(config?.url)) {
187+
response.data = parseV1ErrorData(response.data)
154188
}
155-
const errorResponse = {
156-
error: data.error || error.message || 'Request Error',
157-
startTime: new Date(error.response.config.traceTimeStart).toLocaleTimeString(),
189+
190+
const data = response.data || {}
191+
const message = data.error || error.message || 'Request Error'
192+
193+
if (shouldNotifyError(config)) {
194+
showErrorMessage(message)
158195
}
159-
return Promise.reject(errorResponse)
196+
197+
return Promise.reject(buildErrorPayload(message, response.config?.traceTimeStart))
160198
}
161199
)

src/api/pipeline.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ export function create(pipeFile: PipeFile) {
4848

4949
export function list() {
5050
return runSQL(
51-
`SELECT name,max(created_at) as created_at FROM greptime_private.pipelines group by name order by created_at desc`
51+
`SELECT name,max(created_at) as created_at FROM greptime_private.pipelines group by name order by created_at desc`,
52+
undefined,
53+
{ suppressErrorToast: true }
5254
).then((result) => {
5355
return result.output[0].records.rows.map((row: any) => {
5456
return {
@@ -139,7 +141,7 @@ export function getPipelineDDL(pipelineName: string, tableName: string) {
139141
db: appStore.database,
140142
},
141143
})
142-
.then((result) => {
144+
.then((result: any) => {
143145
return result.sql.sql
144146
})
145147
}

0 commit comments

Comments
 (0)