I am using https://github.com/kriskowal/q to create a (deeply) nested set of promises. Errors are not propagating out to the outermost .catch() the way I was expecting. See the html = tmpl_func(data_)
line in my coffeescript:
$exp.setEventResponse = (event_str, pre_func, tmpl_list, post_func) ->
$(document).on(event_str, (_event, args) ->
console.log("on: #{event_str}. #{args}")
data = args or {}
data._start_ts = now = Date.now()
data.trigger = $exp.trigger
#return data
p = Q(data)
if pre_func
p = p.then( (data_) ->
pre_func(data_)
).then( (data_) ->
if data_._start_ts != now
throw new Error("#{event_str}_pre must return data or Q(...).then(() -> data)")
return data_
)
p.then( (data_) ->
pp = Q(data_)
if tmpl_list or data_.extraTmpl_list
console.log(tmpl_list.concat(data_.extraTmpl_list or []))
for tmpl_args in tmpl_list.concat(data_.extraTmpl_list or [])
closure_func = (ppp, tmpl_args) ->
return ppp.then((data_) ->
if tmpl_args.length == 3
[selector, tmpl_func, replace] = tmpl_args
else
[selector, tmpl_func] = tmpl_args
replace = true
try
html = tmpl_func(data_)
catch error
console.log error
throw error
if replace
$(selector).replaceWith(html)
else
$(selector).html(html)
return data_
)
pp = closure_func(pp, tmpl_args)
pp = pp.then( (data_) ->
if data_._start_ts != now
throw new Error("#{event_str}_tmpl must return data or Q(...).then(() -> data)")
return data_
)
return pp
)
if post_func
p = p.then( (data_) ->
post_func(data_)
).then( (data_) ->
if data_._start_ts != now
throw new Error("#{event_str}_post must return data or Q(...).then(() -> data)")
return data_
)
p.then( (data_) ->
data_._end_ts = Date.now()
duration_sec = (data_._end_ts - data_._start_ts) / 1000.0
if duration_sec >= _durationLogThreshold_sec
console.log("Event #{event_str} duration: #{duration_sec} sec")
return data_
).catch( (reason) ->
console.log(reason)
#alert(reason)
).done()
)
Called like so:
$exp.setEventResponse('showScan',
showScan_pre, [['#content', showScan_tmpl]], showScan_post)
If the tmpl_func
raises an error it doesn't trigger the .catch( (reason) ->
near the end of the snippet. I'd like to be able to take care of any errors that happen inside of the closure_func
(for example, if there's an error running a script that was triggered from script tags in the html
when sending it into replaceWith
).
Am I using promises properly?
How can I handle errors from nested promises properly?
Am I misunderstanding something about what should be happening with catch
?
You are missing a reassignment to p
:
p.then( (data_) ->
pp = Q(data_)
…
return pp
)
should needs to be
p = p.then( (data_) ->
pp = Q(data_)
…
return pp
)
Otherwise you are just branching the chain, but executing the post_func
right after the pre_func
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.