| 'use strict'; | 
| const retry = require('retry'); | 
|   | 
| class AbortError extends Error { | 
|     constructor(message) { | 
|         super(); | 
|   | 
|         if (message instanceof Error) { | 
|             this.originalError = message; | 
|             ({message} = message); | 
|         } else { | 
|             this.originalError = new Error(message); | 
|             this.originalError.stack = this.stack; | 
|         } | 
|   | 
|         this.name = 'AbortError'; | 
|         this.message = message; | 
|     } | 
| } | 
|   | 
| function decorateErrorWithCounts(error, attemptNumber, options) { | 
|     // Minus 1 from attemptNumber because the first attempt does not count as a retry | 
|     const retriesLeft = options.retries - (attemptNumber - 1); | 
|   | 
|     error.attemptNumber = attemptNumber; | 
|     error.retriesLeft = retriesLeft; | 
|   | 
|     return error; | 
| } | 
|   | 
| module.exports = (input, options) => new Promise((resolve, reject) => { | 
|     options = Object.assign({ | 
|         onFailedAttempt: () => {}, | 
|         retries: 10 | 
|     }, options); | 
|   | 
|     const operation = retry.operation(options); | 
|   | 
|     operation.attempt(attemptNumber => Promise.resolve(attemptNumber) | 
|         .then(input) | 
|         .then(resolve, error => { | 
|             if (error instanceof AbortError) { | 
|                 operation.stop(); | 
|                 reject(error.originalError); | 
|             } else if (error instanceof TypeError) { | 
|                 operation.stop(); | 
|                 reject(error); | 
|             } else if (operation.retry(error)) { | 
|                 decorateErrorWithCounts(error, attemptNumber, options); | 
|                 options.onFailedAttempt(error); | 
|             } else { | 
|                 decorateErrorWithCounts(error, attemptNumber, options); | 
|                 options.onFailedAttempt(error); | 
|                 reject(operation.mainError()); | 
|             } | 
|         }) | 
|     ); | 
| }); | 
|   | 
| module.exports.AbortError = AbortError; |