Как засетать данные в стор MobX при повторном запросе из Axios interceptor?

Когда accessToken протухает, interceptor отлавливает ошибку, обновляет токен и повторяет запрос. Запрос повторяется, но данные не записываются в store. Как это можно реализовать?

  (response: AxiosResponse) => {
    return response
  },
  async (error: unknown) => {
    if (isAxiosError(error)) {
      if (error.response?.status === StatusCode.Unauthorized) {
        if (error.config?.url === Endpoints.updateToken) {
          return Promise.reject(error)
        } else {
          try {
            const params = error.config || undefined

            await authStore.updateToken(params)
          } catch (updateError) {
            return Promise.reject(updateError)
          }
        }
      }
    }

    return Promise.reject(error)
  }
)


  async updateToken(
    params: InternalAxiosRequestConfig | undefined
  ) {
    try {
      const newToken = await authApi.updateToken()

      setToLocalStorage(StorageKeys.AccessToken, newToken)

      if (params) {
        params.headers.Authorization = `Bearer ${newToken}`

        const repeatedRequest = await instance.request(params)

        // ???

      }
    } catch (error) {
      return Promise.reject(error)
    }
  }

Я пробовал повторять не запрос, а экшен, доставая дынные из axios error.config, но запросы с path параметрами сбили меня с толку "/api/v1/posts/{postId}/comments/{commentId}/answers/{answerId}/likes"


Ответы (1 шт):

Автор решения: Sun-ny11

Промис, возвращённый из интерцептора, попадёт в экшен, вызвавший ошибку.

instance.interceptors.response.use(
  (response: AxiosResponse) => {
    return response
  },
  async (error: unknown) => {
    if (isAxiosError(error)) {
      if (error.response?.status === StatusCode.Unauthorized) {
        if (error.config?.url === Endpoints.updateToken) {
          return Promise.reject(error)
        } else {
          try {
            const repeatedResponse = await authStore.updateToken(error.config)

            return Promise.resolve(repeatedResponse) // вернется в экшен
          } catch (updateError) {
            return Promise.reject(updateError)
          }
        }
      }
    }

    return Promise.reject(error)
  }
)
//_____________store_____________

  async me() {
    try {
      const profile = await authApi.me() // повторный запрос, вернет промис из interceptor
      
      runInAction(() => {
        this.profile = profile
      })
    } catch (error) {
      throw Error
    }
  }

async updateToken(params: InternalAxiosRequestConfig | undefined) {
    try {
      if (localStorage.getItem(StorageKeys.AccessToken)) {
        const newToken = await authApi.updateToken()

        setToLocalStorage(StorageKeys.AccessToken, newToken)

        if (params) {
          params.headers.Authorization = `Bearer ${newToken}`

          const repeatedRequest = await instance.request(params)

          return repeatedRequest
        }
      }
    } catch (error) {
      return Promise.reject(error)
    }
  } 
→ Ссылка