So I have a form that submits with the following function:
const formSubmit = async (formData) => {
const response = await SubmissionsResource.create(formData)
const { data, status } = response
console.log('Request completed.')
if (status === 201) {
toast.success('Submission created.')
} else {
toast.error('Something went wrong.')
console.error(data)
}
}
Which uses the following:
const SubmissionsResource = {
create: ({ formData }) => (
Request.privatePost(apiUrl('submissions'), formData)
),
}
Which uses the following:
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 })
)
}
When the response is successful, I always see the "Request completed" log, and I see the toast.success
message. However, when the request fails, I never see the "Request completed" log, nor the toast.error
message.
The axios interceptor should retry once if the response comes back unauthorized (401 status code), which it successfully does, and in all other cases, reject the promise and return the error.
Request.privateRequest
should reject the promise and return the error to Request.privatePost
, which should return back to SubmissionsResource.create
, and then finally to formSubmit
. However, instead of completing the promise and returning an error, it just halts the entire function and doesn't ever get to the "Request completed" log.
I'm assuming this is due to an incorrect understanding with promises on my end, but I can't figure out what that is. Why isn't the promise being completed and continuing on to the next line within formSubmit
?
CodePudding user response:
By returning Promise.reject(), you're telling axios to reject the promise returned by the network request, but the calling code doesn't catch any rejection.
Try try-ing:
const formSubmit = async (formData) => {
try {
const response = await SubmissionsResource.create(formData)
const { data, status } = response
console.log('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.');
}
}