Обещание не выполняться при отказе

Итак, у меня есть форма, которая отправляется со следующей функцией:

const formSubmit = async (formData) => {
  const response = await SubmissionsResource.create(formData)
  const { data, status } = response
  console.info('Request completed.')
  if (status === 201) {
    toast.success('Submission created.')
  } else {
    toast.error('Something went wrong.')
    console.error(data)
  }
}

Который использует следующее:

const SubmissionsResource = {
  create: ({ formData }) => (
    Request.privatePost(apiUrl('submissions'), formData)
  ),
}

Который использует следующее:

export const Request = {
  privateRequest: ({ data, method, params, url }) => {
    axios.interceptors.request.use((request) => {
      request.headers.authorization = getBearerToken()
      return request
    }, (error) => Promise.reject(error))

    axios.interceptors.response.use(
      (response) => response,
      async (error) => {
        const originalRequest = error.config

        // If request is coming from a sign in attempt
        if (error.response.status === 401 && originalRequest.url.includes('auth/token')) {
          return Promise.reject(error)
        }

        // If request is coming from elsewhere, assume token might be expired
        if (error.response.status === 401 && !originalRequest._retry) {
          originalRequest._retry = true
          const refresh_token = LocalStorageService.getRefreshToken()
          const response = await axios.post(
            `${API_BASE}/oauth/token`,
            { client_id, client_secret, grant_type: 'refresh_token', refresh_token }
          )
          if (response.status === 200) {
            LocalStorageService.setUser(response.data)
            axios.defaults.headers.common.Authorization = getBearerToken()
            return axios(originalRequest)
          }
          return Promise.reject(error)
        }
        return Promise.reject(error)
      }
    )
    return axios({ method, url, data, params })
  },
  privatePost: (url, data) => (
    Request.privateRequest({ method: 'post', data, url })
  )
}

Когда ответ успешен, я всегда вижу журнал «Запрос выполнен» и вижу сообщение toast.success. Однако, когда запрос завершается неудачно, я никогда не вижу журнал «Запрос выполнен» или сообщение toast.error.

Перехватчик axios должен повторить попытку один раз, если ответ возвращается неавторизованным (код состояния 401), что он успешно делает, а во всех остальных случаях отклоняет обещание и возвращает ошибку.

Request.privateRequest должен отклонить обещание и вернуть ошибку Request.privatePost, который должен вернуться обратно к SubmissionsResource.create, а затем, наконец, к formSubmit. Однако вместо того, чтобы выполнить промис и вернуть ошибку, он просто останавливает всю функцию и никогда не попадает в журнал «Запрос выполнен».

Я предполагаю, что это связано с неправильным пониманием обещаний с моей стороны, но я не могу понять, что это такое. Почему обещание не завершается и не переходит на следующую строку в formSubmit?

Я не знаю ни одного из этих API, но, как правило, вы можете throw new Error(x) вместо return Promise.reject(x) заставить цепочки промисов «распутываться». Попробуйте это и посмотрите, исправит ли это .... Еще одна вещь, которую вы можете попробовать: используйте отладчик по умолчанию, попробуйте установить точки останова и посмотрите, куда идет поток управления и что библиотека делает с результатом.

Domi 05.04.2022 23:44
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
33
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Возвращая Promise.reject(), вы говорите axios отклонить обещание, возвращенное сетевым запросом, но вызывающий код не получает никакого отклонения.

Попробуйте попробовать:

const formSubmit = async (formData) => {
  try {
    const response = await SubmissionsResource.create(formData)
    const { data, status } = response
    console.info('Request completed.');
    toast.success('Submission created.')
  } catch(error) {
    if (error.response.status === 401)
      toast.error('Bad news: 401.');
    else 
      toast.error('Some other kind of bad news.');
  }
}

Да, это было проблемой. Спасибо!

Doug 06.04.2022 04:20

Другие вопросы по теме

Похожие вопросы