import * as retry from 'async/retry' import * as Bluebird from 'bluebird' import { Model } from 'sequelize-typescript' import { logger } from './logger' type RetryTransactionWrapperOptions = { errorMessage: string, arguments?: any[] } function retryTransactionWrapper ( functionToRetry: (...args) => Promise | Bluebird, options: RetryTransactionWrapperOptions ): Promise { const args = options.arguments ? options.arguments : [] return transactionRetryer(callback => { functionToRetry.apply(this, args) .then((result: T) => callback(null, result)) .catch(err => callback(err)) }) .catch(err => { logger.error(options.errorMessage, { err }) throw err }) } function transactionRetryer (func: (err: any, data: T) => any) { return new Promise((res, rej) => { retry({ times: 5, errorFilter: err => { const willRetry = (err.name === 'SequelizeDatabaseError') logger.debug('Maybe retrying the transaction function.', { willRetry, err }) return willRetry } }, func, (err, data) => err ? rej(err) : res(data)) }) } function updateInstanceWithAnother > (instanceToUpdate: Model, baseInstance: Model) { const obj = baseInstance.toJSON() for (const key of Object.keys(obj)) { instanceToUpdate.set(key, obj[key]) } } // --------------------------------------------------------------------------- export { retryTransactionWrapper, transactionRetryer, updateInstanceWithAnother }