funcool/promesa

Issues with "special promises"

martinklepsch opened this issue · 7 comments

Hey! I'm not sure how to best describe this but Firebase's JS SDK uses special promises. I think they use Closure under the hood so it might be goog.promise but it's advanced compiled so it's not really apparent or usable.

While upgrading from 4.0.2 to 5.0.0 these promises no longer work with promesa out of the box.

    (-> (firebase/auth)
        (.-currentUser)
        (.getIdToken)
        (p/then (fn [token] (println token))))

As per the docs getIdToken should return a promise. Replacing p/then with .then does indeed work.

The error in the console looks like this:

Hmm, can you try it wit the latest version of promesa (5.1.0), i think this should be fixed, unless the promise object returned from firebase api does not inherit from Object, so in this case you dont have other choice that wrap it in (p/promise firebase-promise-here).

Huh, it does work now. Will blame this on caching, sorry for the noise and thanks for the quick help! 🙇

@niwinz actually it seemed flaky or not quite deterministic when this occurs. I meant to update this thread for a few weeks but also don't really have more information to provide. A co-worker now attempted upgrading promesa independently of my attempt and ran into the same issues with 5.1.0.

Is there any additional information that would be helpful to figure this out?

Hi @martinklepsch i think i found the issue after a bit researching, i'll try to fix it.
In any case, the most safe way to treat with "fake" or "other promises" is wrapping them with p/promise (that coerces something is that promise-like to js/Promise)

That's great, thanks for looking into it again.

Yeah, I was aware I could just fix it with p/promise but I wanted to keep the incentive to understand if this is an issue with promesa which I probably wouldn't have done if I had just thrown in p/promise 🙃

Released: 6.0.0 (with minor "breaking" change that removes the old and already deprecated for a while the promesa.core/alet alias for promesa.core/let)

cljs.user=> (require '[promesa.core :as p])
nil
cljs.user=> (def fake-promise #js {:then (fn [f] (f 1))})
#'cljs.user/fake-promise
cljs.user=> (p/then fake-promise (fn [v] (prn "Res:" v)))
#<Promise[~]>
"Res:" 1

Fantastic that seems to have fixed the issue we were seeing! Thanks a lot! 🙌