I have to return an await function from my code block, now when the await function is called and failed on the first try, I want to retry it again and if it failed on the second time.. I will show an error message.
THIS IS MY CODE
async makeCall(inputs: myInputs): Promise<Instance> {
const emailOptions: CreateOptions = {
to: inputs.toPhone,
from: this.config.accountPhoneNumber
};
if (inputs.toPhone) {
emailOptions.sendText = inputs.toPhone;
}
return await this.sample.create(emailOptions);
}
I WANT SOMETHING LIKE THIS OR ANY SUGGESTION? LIKE Retry from RxJs
for(var i = 0; i < 1; i++)
{
var result = await this.sample.create(emailOptions);
if(result)
{
// break the loop
return result;
}
}
// if we land here, so the number of retries was exceeded
throw Error("...");
You can use this article code which seems to be exactly what you need. It has support for number of retries and custom error message.
import './style.css';
let i = 0;
const promiseFn = () => {
const condition = i === 0;
i++;
return condition ? Promise.reject() : Promise.resolve();
};
const retryWithDelay = async (
fn: any,
retries = 3,
finalErr = 'Retry failed'
) => {
try {
// try
await fn();
} catch (err) {
// if no retries left
// throw error
if (retries <= 0) {
console.log('error');
return Promise.reject(finalErr);
}
//recursively call the same func
return retryWithDelay(fn, retries - 1, finalErr);
}
};
retryWithDelay(promiseFn, 2)
.then(() => {
console.log('final success');
})
.catch(() => {
console.log('final error');
});
Sometimes, a generic approach, without RxJs is simpler and better ;)
Here's generic (flexible and reusable) approach to retrying an async operation:
// retry-status object:
// - "index": retry index, starting from 0
// - "duration": retry overall duration, in ms
// - "error": last error, if available
type RetryStatus = { index: number, duration: number, error?: any };
// retry-status callback;
type RetryCB<T> = (s: RetryStatus) => T;
type RetryOptions = {
// maximum number of retries (infinite by default),
// or a callback to indicate the need for another retry;
retry?: number | RetryCB<Boolean>,
// retry delays, in ms, or a callback that returns them;
delay?: number | RetryCB<number>,
// error notifications;
error?: RetryCB<void>
};
// retries async operation returned from "func" callback, according to options;
// note that "func()" will receive "error" = undefined when "index" = 0.
function retryAsync<T>(func: RetryCB<Promise<T>>, options?: RetryOptions) {
const start = Date.now();
let index = 0, e: any;
let {retry = Number.POSITIVE_INFINITY, delay = -1, error} = options ?? {};
const s = () => ({index, duration: Date.now() - start, error: e});
const c: () => Promise<T> = () => func(s()).catch(err => {
e = err;
typeof error === 'function' && error(s());
const r = typeof retry === 'function' ? retry(s()) : retry--;
const d = typeof delay === 'function' ? delay(s()) : delay;
index++;
const t = () => r ? c() : Promise.reject(e);
return d >= 0 ? (new Promise(a => setTimeout(a, d))).then(t) : t();
});
return c();
}
You can still use it with RxJs, of course, because it is 100% generic. You just pass it a function that creates your async request, plus some optional parameters.
The code above was taken from this gist.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With