diff --git a/front/src/init/axios.ts b/front/src/init/axios.ts index 88a90621d..8d457903e 100644 --- a/front/src/init/axios.ts +++ b/front/src/init/axios.ts @@ -117,18 +117,27 @@ export const install: InitModule = ({ store, router }) => { return Promise.reject(error) }) - const refreshAuth = (failedRequest: AxiosError) => { + const refreshAuth = async (failedRequest: AxiosError) => { if (store.state.auth.oauth.accessToken) { console.log('Failed request, refreshing auth…') - // maybe the token was expired, let's try to refresh it - return store.dispatch('auth/refreshOauthToken').then(() => { - if (failedRequest.response) { - failedRequest.response.config.headers ??= {} - failedRequest.response.config.headers.Authorization = store.getters['auth/header'] + + try { + // maybe the token was expired, let's try to refresh it + await store.dispatch('auth/refreshOauthToken') + } catch (error) { + if ((error as BackendError).backendErrors.includes('invalid_grant')) { + setTimeout(() => store.dispatch('auth/logout'), 0) } - return Promise.resolve() - }) + return Promise.reject(error) + } + + if (failedRequest.response) { + failedRequest.response.config.headers ??= {} + failedRequest.response.config.headers.Authorization = store.getters['auth/header'] + } + + return Promise.resolve() } return Promise.resolve() diff --git a/front/src/types.ts b/front/src/types.ts index a6d95ed8c..64df678f0 100644 --- a/front/src/types.ts +++ b/front/src/types.ts @@ -213,7 +213,7 @@ export interface Listening { // API stuff // eslint-disable-next-line -export interface APIErrorResponse extends Record {} +export interface APIErrorResponse extends Record {} export interface BackendError extends AxiosError { isHandled: boolean diff --git a/front/src/utils/index.ts b/front/src/utils/index.ts index 1fd4b0f3d..d865997a9 100644 --- a/front/src/utils/index.ts +++ b/front/src/utils/index.ts @@ -4,22 +4,27 @@ import { startCase } from 'lodash-es' export function parseAPIErrors (responseData: APIErrorResponse, parentField?: string): string[] { const errors = [] + + const getErrorMessage = (err: string, fieldName?: string) => err.toLocaleLowerCase().includes('this field ') + ? `${fieldName}: ${err}` + : err + for (const [field, value] of Object.entries(responseData)) { let fieldName = startCase(field.replace(/_/g, ' ')) if (parentField) { fieldName = `${parentField} - ${fieldName}` } - if (Array.isArray(value)) { - errors.push(...value.map(err => { - if (typeof err === 'string') { - return err.toLocaleLowerCase().includes('this field ') - ? `${fieldName}: ${err}` - : err - } + if (typeof value === 'string') { + errors.push(getErrorMessage(value, fieldName)) + continue + } - return startCase(err.code.replace(/_/g, ' ')) - })) + if (Array.isArray(value)) { + errors.push(...value.map(err => typeof err === 'string' + ? getErrorMessage(err, fieldName) + : startCase(err.code.replace(/_/g, ' ')) + )) continue }