mirror of
https://github.com/flynx/types.js.git
synced 2025-10-28 10:00:08 +00:00
reworked error handling in Promise's .iter(..)/.seqiter(..)/..
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
0b8a9d98ab
commit
ca4983c630
141
Promise.js
141
Promise.js
@ -163,8 +163,8 @@ module.packed =
|
||||
return that.handle(packed, ...handlers) }) }
|
||||
|
||||
var handleSTOP = function(err){
|
||||
stop = true
|
||||
if(err && err === Array.STOP){
|
||||
stop = true
|
||||
return []
|
||||
} else if(err && err instanceof Array.STOP){
|
||||
return err.value }
|
||||
@ -174,66 +174,78 @@ module.packed =
|
||||
var map = Array.STOP ?
|
||||
'smap'
|
||||
: 'map'
|
||||
return packed
|
||||
// NOTE: we do not need to rapack after this because the handlers
|
||||
// will get the correct (unpacked) values and it's their
|
||||
// responsibility to pack them if needed...
|
||||
// NOTE: this removes the need to handle sub-arrays unless they are
|
||||
// in a promise...
|
||||
.flat()
|
||||
[map](
|
||||
function(elem){
|
||||
return elem instanceof Promise ?
|
||||
elem.then(function(elem){
|
||||
if(stop){
|
||||
return [] }
|
||||
try{
|
||||
var has_promise = false
|
||||
// NOTE: do the same thing handle(..) does
|
||||
// but on a single level, without expanding
|
||||
// arrays...
|
||||
if(elem instanceof Array){
|
||||
var res = elem.map(function(elem){
|
||||
var res = elem instanceof Promise ?
|
||||
elem.then(function(elem){
|
||||
try{
|
||||
return !stop ?
|
||||
handler(elem)
|
||||
: []
|
||||
} catch(err){
|
||||
return handleSTOP(err) } })
|
||||
: handler(elem)
|
||||
has_promise = has_promise
|
||||
|| res instanceof Promise
|
||||
return res })
|
||||
// non-arrays...
|
||||
} else {
|
||||
// NOTE: we are wrapping the result in an array to
|
||||
// normalize it with the above...
|
||||
res = [handler(elem)]
|
||||
has_promise = has_promise
|
||||
|| res[0] instanceof Promise }
|
||||
try{
|
||||
return packed
|
||||
// NOTE: we do not need to rapack after this because the handlers
|
||||
// will get the correct (unpacked) values and it's their
|
||||
// responsibility to pack them if needed...
|
||||
// NOTE: this removes the need to handle sub-arrays unless they are
|
||||
// in a promise...
|
||||
.flat()
|
||||
[map](
|
||||
function(elem){
|
||||
return elem instanceof Promise ?
|
||||
elem
|
||||
.then(function(elem){
|
||||
if(stop){
|
||||
return [] }
|
||||
try{
|
||||
var has_promise = false
|
||||
// NOTE: do the same thing handle(..) does
|
||||
// but on a single level, without expanding
|
||||
// arrays...
|
||||
if(elem instanceof Array){
|
||||
var res = elem
|
||||
.map(function(elem){
|
||||
var res = elem instanceof Promise ?
|
||||
elem.then(function(elem){
|
||||
try{
|
||||
return !stop ?
|
||||
handler(elem)
|
||||
: []
|
||||
}catch(err){
|
||||
return handleSTOP(err) } })
|
||||
: handler(elem)
|
||||
has_promise = has_promise
|
||||
|| res instanceof Promise
|
||||
return res })
|
||||
// non-arrays...
|
||||
} else {
|
||||
// NOTE: we are wrapping the result in an array to
|
||||
// normalize it with the above...
|
||||
res = [handler(elem)]
|
||||
has_promise = has_promise
|
||||
|| res[0] instanceof Promise }
|
||||
|
||||
// compensate for the outer .flat()...
|
||||
// NOTE: at this point res is always an array...
|
||||
return has_promise ?
|
||||
// NOTE: since we are already in a promise
|
||||
// grouping things here is not a big
|
||||
// deal, however this is needed to link
|
||||
// nested promises with the containing
|
||||
// promise...
|
||||
Promise.all(res)
|
||||
.then(function(res){
|
||||
return res.flat() })
|
||||
: res.flat()
|
||||
} catch(err){
|
||||
return handleSTOP(err) } })
|
||||
: handler(elem) },
|
||||
// onerror...
|
||||
function(err){
|
||||
stop = true
|
||||
typeof(onerror) == 'function'
|
||||
&& onerror(err) }) },
|
||||
// compensate for the outer .flat()...
|
||||
// NOTE: at this point res is always an array...
|
||||
return has_promise ?
|
||||
// NOTE: since we are already in a promise
|
||||
// grouping things here is not a big
|
||||
// deal, however this is needed to link
|
||||
// nested promises with the containing
|
||||
// promise...
|
||||
Promise.all(res)
|
||||
.then(function(res){
|
||||
return res.flat() })
|
||||
: res.flat()
|
||||
} catch(err){
|
||||
return handleSTOP(err) } })
|
||||
// err...
|
||||
.catch(function(err){
|
||||
stop = true
|
||||
typeof(onerror) == 'function'
|
||||
&& onerror(err)
|
||||
return [] })
|
||||
: handler(elem) })
|
||||
}catch(err){
|
||||
// err
|
||||
if(err !== Array.STOP
|
||||
&& !(err instanceof Array.STOP)
|
||||
&& typeof(onerror) == 'function'){
|
||||
onerror(err)
|
||||
return [] }
|
||||
throw err } },
|
||||
//
|
||||
// unpack(<packed>)
|
||||
// -> <array>
|
||||
@ -822,12 +834,17 @@ object.Constructor('IterablePromise', Promise, {
|
||||
|
||||
// populate new instance...
|
||||
if(promise){
|
||||
// handle onerror(..)
|
||||
var handleError = function(err){
|
||||
onerror ?
|
||||
promise.resolve(onerror(err))
|
||||
: promise.reject(err) }
|
||||
// handle/pack input data...
|
||||
if(handler != 'raw'){
|
||||
//list = list instanceof IterablePromise ?
|
||||
list = list instanceof this.constructor ?
|
||||
obj.__handle(list.__packed, handler, onerror)
|
||||
: obj.__pack(list, handler, onerror) }
|
||||
obj.__handle(list.__packed, handler, handleError)
|
||||
: obj.__pack(list, handler, handleError) }
|
||||
Object.defineProperty(obj, '__packed', {
|
||||
value: list,
|
||||
enumerable: false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ig-types",
|
||||
"version": "6.24.24",
|
||||
"version": "6.25.0",
|
||||
"description": "Generic JavaScript types and type extensions...",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
||||
45
test.js
45
test.js
@ -451,6 +451,51 @@ var cases = test.Cases({
|
||||
'.seqiter(..): STOP(..): delayed')
|
||||
|
||||
// XXX test .seqstartiter(..)
|
||||
|
||||
|
||||
|
||||
// error...
|
||||
for(var iter of ['iter', 'seqiter', 'seqstartiter']){
|
||||
assert(
|
||||
await Promise[iter]([1,2,Promise.resolve(3),4,5],
|
||||
function(e){
|
||||
if(e == 2){
|
||||
throw 'ERROR' }
|
||||
return e })
|
||||
.catch(function(err){
|
||||
return 'done' })
|
||||
== 'done',
|
||||
`.${iter}(..): .catch(..)`)
|
||||
assert(
|
||||
await Promise[iter]([1,2,Promise.resolve(3),4,5],
|
||||
function(e){
|
||||
if(e == 2){
|
||||
throw 'ERROR' }
|
||||
return e },
|
||||
function(err){
|
||||
return 'done' })
|
||||
== 'done',
|
||||
`.${iter}(..): onerror(..)`)
|
||||
assert(
|
||||
await Promise[iter]([1,2,Promise.resolve(3),4,5],
|
||||
function(e){
|
||||
if(e == 3){
|
||||
throw 'ERROR' }
|
||||
return e },
|
||||
function(err){
|
||||
return 'done' })
|
||||
== 'done',
|
||||
`.${iter}(..): edge onerror(..)`)
|
||||
assert(
|
||||
await Promise[iter]([1,2,Promise.resolve(3),4,5],
|
||||
function(e){
|
||||
if(e == 4){
|
||||
throw 'ERROR' }
|
||||
return e },
|
||||
function(err){
|
||||
return 'done' })
|
||||
== 'done',
|
||||
`.${iter}(..): late onerror(..)`) }
|
||||
},
|
||||
|
||||
// Date.js
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user