简体   繁体   中英

JS Q Promises not propagating errors

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM