funcool

lilactown 2024-08-14T18:36:23.204429Z

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 rejecting

niwinz 2024-08-19T07:35:36.632859Z

p/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

👍🏻 1
niwinz 2024-08-19T07:35:47.692869Z

so now I understand what really happens

niwinz 2024-08-19T07:40:39.628809Z

I will try to take some time today or tomorrow for look on this issues.

🙏🏻 1
niwinz 2024-08-19T18:36:50.843169Z

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

niwinz 2024-08-17T15:44:29.598989Z

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.

niwinz 2024-08-17T15:48:42.525109Z

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.

lilactown 2024-08-17T16:15:12.146449Z

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.

lilactown 2024-08-20T15:49:30.507579Z

I'll see if I can try a checkout (we use lein) sometime this week