如果发生错误,如何调用 API 两次?
How to call an API twice if there is an error occurred?
我有一个内部 API 想要 post 数据。取决于某些情况,我看到错误。所以我想做的是在发生错误时再次调用它。
我所做的是创建一个计数器将其传递给函数并递归调用函数,如下所示。这给了我如下错误:
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
我是这样调用函数的:
....
private RETRY_API = 1;
....
try {
await this.callAPI(request, this.RETRY_API);
} catch (error) {
console.log('error', error);
}
这个程序永远不会到达上面的 catch 块。
这是我调用 API:
的实际函数
private async callAPI(request, retry) {
return new Promise((resolve, reject) => {
someService.postApiRequest('api/url', request, async(err: any, httpCode: number, data) => {
if (this.RETRY_API == 2) {
return reject(err);
} else if (err) {
this.callAPI(request, retry);
this.RETRY_API++;
} else if ( httpCode !== 200 ) {
this.RETRY_API = 2;
// some stuff
} else {
this.RETRY_API = 2;
// some stuff
return resolve(data);
}
});
})
}
不确定我错过了什么。如果有更好的方法在发生错误时调用 API 两次,请告诉我,那就太好了。
看来您需要在 callAPI
函数中的 this.callAPI(request, retry);
行的开头添加 return await
。
同样,有些条件块不会解决或拒绝承诺。虽然它可能工作正常,但它被认为是不好的做法。您想要解决或拒绝承诺。
当我使用 axios' interceptors functions.
收到错误时,我已经完成了第二次调用 API
这是您可以查看的代码片段:
axios.interceptors.response.use(
// function called on a successful response 2xx
function (response) {
return response;
},
// function called on an error response ( not 2xx )
async function (error) {
const request = error.config as AxiosRequestConfig;
// request is original API call
// change something about the call and try again
// request.headers['Authorization'] = `Bearer DIFFERENT_TOKEN`;
// return axios(request)
// or Call a different API
// const new_data = await axios.get(...).then(...)
// return new_data
// all else fails return the original error
return Promise.reject(error)
}
);
尝试替换
if (this.RETRY_API == 2)
和
if (this.RETRY_API > 1)
让我们以不同的方式组织。首先,api...
的 promise-wrapper
private async callAPI(request) {
return new Promise((resolve, reject) => {
someService.postApiRequest('api/url', request,(err: any, httpCode: number, data) => {
err ? reject(err) : resolve(data);
});
});
}
一个使用 setTimeout 的实用程序函数...
async function delay(t) {
return new Promise(resolve => setTimeout(resolve, t));
}
现在,一个延迟调用和重试的函数...
private async callAPIWithRetry(request, retryCount=2, retryDelay=2000) {
try {
return await callAPI(request);
} catch (error) {
if (retryCount <= 0) throw err;
await delay(retryDelay);
return callAPIWithRetry(request, retryCount-1, retryDelay);
}
}
如果你不能在 api 上强制失败以其他方式测试错误路径,你至少可以试试这个...
private async callAPIWithRetry(request, retryCount=2, retryDelay=2000) {
try {
// I hate to do this, but the only way I can test the error path is to change the code here to throw an error
// return await callAPI(request);
await delay(500);
throw("mock error");
} catch (error) {
if (retryCount <= 0) throw err;
await delay(retryDelay);
return callAPIWithRetry(request, retryCount-1, retryDelay);
}
}
我有一个内部 API 想要 post 数据。取决于某些情况,我看到错误。所以我想做的是在发生错误时再次调用它。
我所做的是创建一个计数器将其传递给函数并递归调用函数,如下所示。这给了我如下错误:
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
我是这样调用函数的:
....
private RETRY_API = 1;
....
try {
await this.callAPI(request, this.RETRY_API);
} catch (error) {
console.log('error', error);
}
这个程序永远不会到达上面的 catch 块。
这是我调用 API:
的实际函数private async callAPI(request, retry) {
return new Promise((resolve, reject) => {
someService.postApiRequest('api/url', request, async(err: any, httpCode: number, data) => {
if (this.RETRY_API == 2) {
return reject(err);
} else if (err) {
this.callAPI(request, retry);
this.RETRY_API++;
} else if ( httpCode !== 200 ) {
this.RETRY_API = 2;
// some stuff
} else {
this.RETRY_API = 2;
// some stuff
return resolve(data);
}
});
})
}
不确定我错过了什么。如果有更好的方法在发生错误时调用 API 两次,请告诉我,那就太好了。
看来您需要在 callAPI
函数中的 this.callAPI(request, retry);
行的开头添加 return await
。
同样,有些条件块不会解决或拒绝承诺。虽然它可能工作正常,但它被认为是不好的做法。您想要解决或拒绝承诺。
当我使用 axios' interceptors functions.
收到错误时,我已经完成了第二次调用 API这是您可以查看的代码片段:
axios.interceptors.response.use(
// function called on a successful response 2xx
function (response) {
return response;
},
// function called on an error response ( not 2xx )
async function (error) {
const request = error.config as AxiosRequestConfig;
// request is original API call
// change something about the call and try again
// request.headers['Authorization'] = `Bearer DIFFERENT_TOKEN`;
// return axios(request)
// or Call a different API
// const new_data = await axios.get(...).then(...)
// return new_data
// all else fails return the original error
return Promise.reject(error)
}
);
尝试替换
if (this.RETRY_API == 2)
和
if (this.RETRY_API > 1)
让我们以不同的方式组织。首先,api...
的 promise-wrapperprivate async callAPI(request) {
return new Promise((resolve, reject) => {
someService.postApiRequest('api/url', request,(err: any, httpCode: number, data) => {
err ? reject(err) : resolve(data);
});
});
}
一个使用 setTimeout 的实用程序函数...
async function delay(t) {
return new Promise(resolve => setTimeout(resolve, t));
}
现在,一个延迟调用和重试的函数...
private async callAPIWithRetry(request, retryCount=2, retryDelay=2000) {
try {
return await callAPI(request);
} catch (error) {
if (retryCount <= 0) throw err;
await delay(retryDelay);
return callAPIWithRetry(request, retryCount-1, retryDelay);
}
}
如果你不能在 api 上强制失败以其他方式测试错误路径,你至少可以试试这个...
private async callAPIWithRetry(request, retryCount=2, retryDelay=2000) {
try {
// I hate to do this, but the only way I can test the error path is to change the code here to throw an error
// return await callAPI(request);
await delay(500);
throw("mock error");
} catch (error) {
if (retryCount <= 0) throw err;
await delay(retryDelay);
return callAPIWithRetry(request, retryCount-1, retryDelay);
}
}