Browse Source

Merge pull request #9873 from nocodb/nc-refresh-token-logic

fix: Handle sharedExecution timeout error in interceptor
develop
Pranav C 2 days ago committed by GitHub
parent
commit
f2a2cd2a55
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 11
      packages/nc-gui/composables/useApi/interceptors.ts
  2. 8
      packages/nc-gui/composables/useSharedExecutionFn.ts

11
packages/nc-gui/composables/useApi/interceptors.ts

@ -1,6 +1,8 @@
import type { Api } from 'nocodb-sdk' import type { Api } from 'nocodb-sdk'
const DbNotFoundMsg = 'Database config not found' const DbNotFoundMsg = 'Database config not found'
const TIMEOUT_RETRY_COUNT = 1
export function addAxiosInterceptors(api: Api<any>) { export function addAxiosInterceptors(api: Api<any>) {
const state = useGlobal() const state = useGlobal()
const router = useRouter() const router = useRouter()
@ -61,6 +63,8 @@ export function addAxiosInterceptors(api: Api<any>) {
return Promise.reject(error) return Promise.reject(error)
} }
let retry = 0
do {
try { try {
const token = await state.refreshToken({ const token = await state.refreshToken({
axiosInstance, axiosInstance,
@ -85,13 +89,18 @@ export function addAxiosInterceptors(api: Api<any>) {
return Promise.reject(refreshTokenError) return Promise.reject(refreshTokenError)
} }
// if shared execution error, don't sign out
if (!(refreshTokenError instanceof SharedExecutionError)) {
await state.signOut({ await state.signOut({
redirectToSignin: !isSharedPage, redirectToSignin: !isSharedPage,
skipApiCall: true, skipApiCall: true,
}) })
return Promise.reject(error) return Promise.reject(error)
} }
if (retry >= TIMEOUT_RETRY_COUNT) return Promise.reject(error)
}
} while (retry++ < TIMEOUT_RETRY_COUNT)
}, },
) )

8
packages/nc-gui/composables/useSharedExecutionFn.ts

@ -1,5 +1,11 @@
import { useStorage, useTimeoutFn } from '@vueuse/core' import { useStorage, useTimeoutFn } from '@vueuse/core'
export class SharedExecutionError extends Error {
constructor(message?: string) {
super(message)
}
}
interface SharedExecutionOptions { interface SharedExecutionOptions {
timeout?: number // Maximum time a lock can be held before it's considered stale - default 5000ms timeout?: number // Maximum time a lock can be held before it's considered stale - default 5000ms
storageDelay?: number // Delay before reading from storage to allow for changes to propagate - default 50ms storageDelay?: number // Delay before reading from storage to allow for changes to propagate - default 50ms
@ -102,7 +108,7 @@ export function useSharedExecutionFn<T>(key: string, fn: () => Promise<T> | T, o
() => { () => {
timedOut = true timedOut = true
localStorage.removeItem(storageLockKey) localStorage.removeItem(storageLockKey)
reject(new Error(`Timeout waiting for result on key ${key}`)) reject(new SharedExecutionError(`Timeout waiting for result on key ${key}`))
}, },
currentLock?.timestamp ? timeout - (Date.now() - currentLock.timestamp) : timeout, currentLock?.timestamp ? timeout - (Date.now() - currentLock.timestamp) : timeout,
) )

Loading…
Cancel
Save