Skip to content

Instantly share code, notes, and snippets.

@soareschen
Last active August 29, 2015 14:02
Show Gist options
  • Save soareschen/cf235ca052e59929f08f to your computer and use it in GitHub Desktop.
Save soareschen/cf235ca052e59929f08f to your computer and use it in GitHub Desktop.
Promise Wrappers
'use strict'
var timeoutPromise = function(timeout, construct) {
return new Promise(function(resolve, reject) {
construct(resolve, reject)
setTimeout(function() {
reject(new Error('timeout error'))
}, timeout)
})
}
var createPromise = function(construct) {
return timeoutPromise(1000, construct)
}
createPromise(function(resolve, reject) {
// forget to fulfill
}).then(function(res) {
console.log('should never get result', res)
}, function(err) {
console.log('got timeout error:', err)
})
'use strict'
var detectDoubleFulfilledPromise = function(construct, errHandler) {
return new Promise(function(resolve, reject) {
var fulfilled = false
var wrap = function(fulfill) {
return function(val) {
if(fulfilled) errHandler(new Error(
'promise is fulfilled multiple time'))
fulfilled = true
fulfill(val)
}
}
construct(wrap(resolve), wrap(reject))
})
}
var createPromise = function(construct) {
return detectDoubleFulfilledPromise(construct, console.trace)
}
createPromise(function(resolve, reject) {
resolve(1)
resolve(2)
}).then(function(res) {
console.log('got result:', res)
})
'use strict'
var domainLib = require('domain')
var domainProtectedPromise = function(construct, errHandler) {
return new Promise(function(resolve, reject) {
var domain = domainLib.create()
domain.on('error', errHandler)
domain.run(function() {
construct(resolve, reject)
})
})
}
var createPromise = function(construct) {
return domainProtectedPromise(construct, console.trace)
}
createPromise(function(resolve, reject) {
process.nextTick(function() {
throw new Error('async error')
resolve(1)
})
}).then(function(res) {
console.log('should never get result', res)
}, function(err) {
console.log('got error', err)
})
'use strict'
var detectUncaughtPromise = function(promise, timeout, prevCaught) {
var wrappedPromise = Object.create(promise)
var forwarded = false
var stack = new Error().stack
wrappedPromise.then = function(onResolved, onRejected) {
forwarded = true
var nextCaught = onRejected ? true : false
var newPromise = promise.then(onResolved, onRejected)
return detectUncaughtPromise(newPromise, timeout, nextCaught)
}
wrappedPromise.catch = function(errHandler) {
forwarded = true
var newPromise = promise.catch(errHandler)
return detectUncaughtPromise(newPromise, timeout, true)
}
setTimeout(function() {
if(forwarded) return
if(!prevCaught) {
console.log('uncaught terminal promise detected.',
'last then() was on:', stack)
} else {
promise.catch(function(err) {
console.log('exception occured inside error handler',
'of last promise chain:', err)
})
}
}, timeout)
return wrappedPromise
}
var createPromise = function(construct) {
var promise = new Promise(construct)
return detectUncaughtPromise(promise, 1000)
}
createPromise(function(resolve, reject) {
reject(1)
}).then(function(res) {
console.log('should never get result')
})
createPromise(function(resolve, reject) {
reject(1)
}).catch(function(err) {
console.log('trying to recover from error', err)
throw new Error('error inside error handler')
console.log('should never managed to recover fully')
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment