Why doesn't compilier help me out with this?

Bcrypt.res

@module("bcrypt") external hash: (string, int) => Promise.t<string> = "hash"
@moduel("bcrypt") external compare: (string, string) => Promise.t<bool> = "compare"

Bcrypt_test.res

let doit = async () => {
  let password = "asdfasdfasdf"
  let hash = await Bcrypt.hash(password, 10)
  let authed = await Bcrypt.compare(password, hash)
  Console.log2("authed", authed)
}
doit()->ignore

Bcrypt_test.bs.mjs

import * as Bcrypt from "bcrypt";

async function doit() {
  var password = "asdfasdfasdf";

  var hash = await Bcrypt.hash(password, 10);
  var authed = await compare(password, hash);
  console.log("authed", authed);
}

doit();

export {
  doit ,
}

Error from running Bcrypt_test.bs.mjs

  var authed = await compare(password, hash);
               ^

ReferenceError: compare is not defined

Compiles just fine. No warnings from VSCode. Did you spot the error? Took me about an hour to find it, and this isn’t the first time this happened. Next time maybe I’ll know what to look for.

1 Like

Yeah it’s a good point, I have misspelled the attribute names at times too without noticing and gotten unexpected behavior, until I catch what is going on.

It would be interesting for some warning or something, but I’m pretty sure they’re mostly ignored by the typechecker…I wonder if the ffi attributes could be handled in a special way, though.

(And I guess in theory someone could weirdly write a ppx that actually consume the attribute moduel with the weird spelling for some reason.)

1 Like

I don’t know if there’s much the compiler can do, because @moduel could be a valid attribute - and determining whether it is or not may be quite time-consuming.

Still, I recommend logging a bug as it could be a nice quality-of-life improvement.

2 Likes