Tengo una API interna que me gustaría publicar datos. Depende de algunos casos, estoy viendo errores. Entonces, lo que me gustaría hacer es volver a llamarlo si ocurre un error.
Lo que hice fue crear un contador para pasarlo a la función y llamar a la función recursivamente como se muestra a continuación. Esto me da el error de la siguiente manera:
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)
Así es como llamo a la función:
.... private RETRY_API = 1; .... try { await this.callAPI(request, this.RETRY_API); } catch (error) { console.log('error', error); }Este programa nunca llega al bloque catch anterior.
Y aquí está mi función real a la que llamo 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); } }); }) }No estoy seguro de lo que me estoy perdiendo. Si hay una mejor manera de llamar a la API dos veces si se produce un error, sería genial si me lo hiciera saber.
Vamos a organizar un poco diferente. Primero, un envoltorio de promesa para la API...
private async callAPI(request) { return new Promise((resolve, reject) => { someService.postApiRequest('api/url', request,(err: any, httpCode: number, data) => { err ? reject(err) : resolve(data); }); }); }Una función de utilidad para usar setTimeout con una promesa...
async function delay(t) { return new Promise(resolve => setTimeout(resolve, t)); }Ahora, una función que llama y vuelve a intentar con retraso...
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); } }Si no puede forzar una falla en la API para probar la ruta de error de otra manera, al menos puede intentar esto ...
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); } }Intenta reemplazar
if (this.RETRY_API == 2)con
if (this.RETRY_API > 1)Parece que necesita agregar return await await al comienzo de la línea this.callAPI(request, retry); en la función callAPI .
De manera similar, hay algunos bloques de condición que no resuelven o rechazan la promesa. Si bien podría funcionar bien, se considera una mala práctica. Quiere resolver o rechazar una promesa.