在这个问题上尝试了 50 多个小时后,我终于放弃了。我在谷歌上搜索了很多,但只能找到对我不起作用的小部分。
我正在使用 NodeJS 和 Axios 发出 API 请求。有 3 次请求失败,我想在放弃之前重试请求 3 次。
我有一个 apiClient 和 apiCalls 类。
我想捕获所有问题并在 apiClient 中重试。
这是我到目前为止所拥有的,在尝试了 30 多个解决方案后,我无法使其正常工作。重试请求尝试只会运行一次,然后错误将杀死它。
apiClient.js:
import axios from 'axios'
import qs from 'querystring'
import config from '../../config/config'
const api = axios.create({
baseURL: config.api.baseUrl,
headers: {
'X-User-Agent': 'API Client ' + config.version,
Accept: 'application/json',
'Content-Type': 'application/json'
},
params: {
user: config.api.user
}
})
api.interceptors.request.use(request => {
console.log(`apiClient (${request.method.toUpperCase()}) URL: ${request.baseURL}${request.url}?` + qs.stringify(request.params))
return request
})
api.interceptors.response.use(
async response => successHandler(response),
async error => errorHandler(error)
)
const errorHandler = async (error) => {
const originalRequest = error.config
// Assume possible CORS error when response is empty
if (typeof error.response === 'undefined') {
console.warn(`apiClient: Caught possible CORS error!`)
return await retryRequest(originalRequest)
}
if (error.response) {
console.warn(`apiClient: FATAL ERROR DETECTED! (HTTP STATUS ${error.response.status}): ${error.request.responseURL}`)
return await retryRequest(originalRequest)
}
// Assuming network error if no HTTP error code
if (isNetworkError(error)) {
console.warn('apiClient: NETWORK ERROR DETECTED!')
return await retryRequest(originalRequest)
}
return Promise.reject(error)
}
const SUCCESS_STATUS_CODES = [
200,
204
]
const successHandler = (response) => {
if (!SUCCESS_STATUS_CODES.includes(response.status)) {
console.log(`successHandler status failed (${response.status}): ${response.request.responseURL}`)
} else {
console.log(`API Response Success (${response.status}): ${response.request.responseURL}`)
}
return response
}
async function retryRequest (request) {
let retryAttempts = 3
for (let retryAttempt = 0; retryAttempt < retryAttempts; retryAttempt++) {
console.warn('Retrying request attempt: ' + (retryAttempt + 1))
return this.transport.request({
method: request.config.method,
url: request.config.url,
params: request.config.params,
withCredentials: true,
})
}
}
function isNetworkError (err) {
return !!err.isAxiosError && !err.response
}
export {
apiClient
}
apiCalls.js 示例:
const version = config.api.version
const datasource = config.api.datasource
class ApiCalls {
async getMarketOrders (regionId, typeId = null) {
const results = []
try {
const response = await api.get(`${version}/markets/${regionId}/orders/`, {
params: {
type_id: typeId
}
})
} catch (e) {
throw new Error(this.errorHandler('getMarketOrders', e))
}
errorHandler (functionName, error) {
return JSON.stringify({ function: functionName, error: error })
}
}
export default ApiCalls
这是在一个函数中调用的:
let regionOrders = await apiClient.getMarketOrders(regionId, typeId)
我尝试了无数不支持网络错误的重试库,仅支持 HTTP 状态代码,因此它们对我不起作用。
谢谢。