Since this is a recurring pattern I really want to understand this.
When writing promises with the new Promise library you need to make sure that the catch has the same type as the previous then.
I am trying to connect to the mongodb (which is a promise). On a success I want to write a message “connected”, and return the instance. If not successful I want to write the error.
On success the type, after resolve, is ClientInstance.t. In case of an error the type is unit.
If I understand correctly I need to create a new type, which combines both, the Ok and the Error. I create a new type using Belt.Result.t<typeWhenOk,typeWhenError>. Since the return type of the catch block is unit. I do this:
@send external connect: t => Promise.t<Belt.Result.t<ClientInstance.t,unit>> = "connect"
But that doesn’t work either. I suppose I am totally misunderstanding how types must work. What am I missing?
The error I get is:
FAILED: src/Play.cmj
Warning number 109 (configured as error)
/home/hacker/rescript/rescriptjul23/src/Play.res:29:3-7
27 │ // After resolve the type is ClientInstance.t
28 │ })
29 │ ->catch(e => {
30 │ let errorMsg = switch e {
31 │ | JsError(obj) =>
Toplevel expression is expected to have unit type.
FAILED: cannot make progress due to previous errors.
(base)
This is the code:
module Mongo = {
module ClientInstance = {
type t
}
module Client = {
type t
@module("mongodb") @new external make: string => t = "MongoClient"
@send
external connect: t => Promise.t<Belt.Result.t<ClientInstance.t, unit>> = "connect"
@send external close: t => unit = "close"
}
}
let uri = "mongodb://localhost:27017"
open Promise
open Mongo
let client = Client.make(uri)
client
->Client.connect
->then(instance => {
Js.log("Connected to MongoDB")
// Before resolve the type is Promise.t<ClientInstance.t>
Ok(instance)->resolve
// After resolve the type is ClientInstance.t
})
⚠ ->catch(e => {
let errorMsg = switch e {
| JsError(obj) =>
switch Js.Exn.message(obj) {
| Some(msg) => msg
| None => "Unknown JS error"
}
| _ => "Some unknown non-JS error"
}
Js.log(errorMsg)
// After resolve the type is unit
Error(errorMsg)->resolve
})
~
What is the best way to fix this in general. What is the pattern?