in CLJS, creating a promesa promise of an error leads to it being rejected; this is surprising to me. An example of where this caused an issue using promesa to write tests:
(p/catch
(p/do
(is (thrown? js/Object (throw (js/Error. "foo"))))
(is true))
(fn [e]
(prn :reject)))
leads to the promise rejecting and the callback passed to catch being run.
In JS, creating a promise of any value only rejects if you throw inside the fn passed to the constructor, the fn calls the reject callback, or it's constructed with Promise.reject. You can in fact construct a promise like:
(js/Promise.resolve (js/Error. "foo"))
(js/Promise. (fn [res rej] (res (js/Error. "foo")))
and it will resolve with the error object instead of rejectingp/do is not a constructor, is a code block. and looks like there is a bug, do block should not return rejected exception on exception value return, it should resolve with value, as is
so now I understand what really happens
I will try to take some time today or tomorrow for look on this issues.
If you can use a git as source (instead of mvn release), point to the latest commit, it should fix the polymorphic coercion on macros
I'm not clearly understand that you trying to do on the first code snippet, but the p/do creates a block of code where if exception is raised, the returned promise will be rejected. Nothing related on how you expect a promise is created. Nothing prevents you to create a promise resolved with an exception as value (screenshot), but in your code you are using a do block which has its own semantics and has nothing in common with promise creation as-is.
on js and cljs and clj, creating a promise of any value only rejects if you throw or return a rejected promise, or call reject inside the create callback. The p/promise constructor uses type inference for knowning if promise should be rejected or resolved. But if you don't want it, just use appropriate p/resolved or p/rejected helpers.
yeah, what I'm trying to argue for is the type inference for p/promise and the other macros like p/do isn't what I expect, stops valid programs from working and that this shouldn't reject
(p/do
(ex-info "foo" {})
"bar")
(p/promise (ex-info "foo" {}))
so if something returns - not throws - a promise, it rejects the chain of promises created.
For CLJS, I narrowed it down to this line in coerce
https://github.com/funcool/promesa/blob/0c5ed6ad033515a2df4b55addea044f60e9653d0/src/promesa/impl/promise.js#L414-L416
I understand if you disagree, but it means that I will need to write a lot of code to work around this behavior in clojure.test where passing assertions return the value they assert on, meaning that a valid passing assertion using thrown? will return the exception and cause the promesa promise chain to reject and fail the test suite.I'll see if I can try a checkout (we use lein) sometime this week