How to reject a promise when using Js.Promise.make()?

Consider the following code:

type value = Value(string)

let f = (): value => {
  Js.Exn.raiseError("Hello!")
}

Js.Promise.make((~resolve, ~reject) => {
  switch f() {
  | exception Js.Exn.Error(error) => reject(. <what goes here?>)
  | Value(value) => resolve(. value)
  }
})

I’m unsure how to call the reject() function. What value can I use where I wrote <what goes here?>

Its argument has type exn, but I’m not sure how to construct a value of type exn that I can pass to reject().

I am planning to resolve this by throwing an exception, rather than calling raise().

For example:

Js.Promise.make((~resolve, ~reject as _) => {
  switch f() {
  | exception Js.Exn.Error(error) => {
      let message = Belt.Option.getWithDefault(Js.Exn.message(error), "Unknown")
      Js.Exn.raiseError(message)
    }
  | Value(value) => resolve(. value)
  }
})

There is a related topic, but I was unsure how to apply that here:

Thanks for any suggestions.

2 Likes

What I did was to bind this constructor with the exn type like so:

@bs.new external makeExn: string => exn = "Error";

Then you can reject(makeExn("exception message"))

3 Likes

exn is the type of ReScript exceptions. You can either use a built-in exception, like Failure, or define your own.

let f = x => Js.Promise.make((~resolve, ~reject) => {
    if x == 1 {
      resolve(. x)
    } else {
      reject(. Failure("x must be 1."))
    }
  })

In your example, you can modify it like this:

- | exception Js.Exn.Error(error) => reject(. <what goes here?>)
+ | exception error => reject(. error)

Js.Exn.Error only catches JS errors, not ReScript error objects.

1 Like

@eleanor that’s a great tip, thank you.

@johnj perfect, exactly what I was looking for, thank you.

1 Like