Build a factory decorator that retries a method a fixed number of times before giving up. The wrapped method fails twice, then succeeds on the third attempt.
function retry(times) {
return function (target, key, descriptor) {
const fn = descriptor.value;
descriptor.value = function (...args) {
for (let i = 0; i < times; i++) {
try { return fn.apply(this, args); }
catch (e) { if (i === times - 1) throw e; }
}
};
return descriptor;
};
}
let attempts = 0;
class Service {
connect() {
attempts++;
if (attempts < 3) throw new Error("fail");
return "connected";
}
}
Object.defineProperty(Service.prototype, 'connect',
retry(3)(Service.prototype, 'connect', Object.getOwnPropertyDescriptor(Service.prototype, 'connect')));
console.log(new Service().connect());
Before you run it, say out loud what it will print. Then open the answer.
What it prints
connected
A factory decorator returns the actual decorator, letting you parameterize behavior. It scales to logging, validation, and error handling.