DEV Community

Discussion on: How to handle a nodeback in ReasonML

Collapse
 
idkjs profile image
Alain

Greetings, sir. I tossed this code into a file and got this error:

 /Users/prisc_000/working/NATIVE/bloody-authenticator/src/NodeBack.re 14:30-33 12 ┆ nodeback( 13 ┆ fun 14 ┆ | Error(err) => raise({j|$err|j}) // Can't access data in this branc h 15 ┆ | Ok(data) => Js.log(data), 16 ┆ ) // Can't access err in this branch This has type: string But somewhere wanted: exn 

code i copied:

let nodeback = f => (. err, result) => switch (err, result) { | (Some(err), None) => f(Js.Result.Error(err)) | (None, Some(result)) => f(Ok(result)) // Throw if APIs break nodeback 'guarantee': | _ => invalid_arg("Nodeback arguments invalid") }; Node.Fs.readFileSync( "/etc/passwd", nodeback( fun | Error(err) => raise({j|$err|j}) // Can't access data in this branch | Ok(data) => Js.log(data), ) // Can't access err in this branch ); 

How would I fix that?

Collapse
 
yawaramin profile image
Yawar Amin • Edited

Hi Alain, somehow I completely missed your comment here. Thanks for pointing out this error. Mistake on my part, can be fixed by swapping out the raise with failwith: | Error(err) => failwith({j|$err|j}) // Can't access data in this branch. raise expects something of type exn, but we are calling it with a string. We should use failwith instead which does take a string.

After that fix there is a second error, because the Node.Fs.readFileSync function doesn't actually take a nodeback. In my example I used a hypothetical function Node.Fs.readFile. I say hypothetical because it's not bound in the libraries shipped with BuckleScript, but of course fs.readFile is a real NodeJS function and you could write a binding fairly easily: nodejs.org/dist/latest-v10.x/docs/...

Anyway here's a full working example:

[@bs.module "fs"] external readFile: ( ~path: string, ~options: { . "encoding": option(string), "flag": option(string), } =?, (. Js.Nullable.t('err), Js.Nullable.t(string)) => unit ) => unit = ""; let nodeback = f => (. err, result) => switch (Js.Nullable.(toOption(err), toOption(result))) { | (Some(err), None) => f(Js.Result.Error(err)) | (None, Some(result)) => f(Ok(result)) // Throw if APIs break nodeback 'guarantee': | _ => invalid_arg("Nodeback arguments invalid") }; let readFile = (~flag=?, ~path, f) => readFile( ~path, ~options={"encoding": Some("utf8"), "flag": flag}, nodeback(f), ); let test = () => readFile( ~path="/etc/passwd", fun | Ok(data) => Js.log(data) // Can't access err in this branch | Error(err) => failwith({j|$err|j}) // Can't access data in this branch ); 
Collapse
 
idkjs profile image
Alain

Thanks for taking the time, sir. I can't get this to run for whatever reason. I got this gist to run, gist.github.com/idkjs/c48dda9f1dba... but when i got to apply the concept, i keep running into problems. Even searched through your book! I will keep at it. Peace to you.

Thread Thread
 
yawaramin profile image
Yawar Amin

My apologies, I should have tested that example more thoroughly. I've now updated my previous comment with a really working code sample. You can run it like this:

$ bsb $ node > const {test} = require('./src/Main.bs') > test()