Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad error message when importing .did that isn't a service #2319

Closed
nomeata opened this issue Feb 6, 2021 · 13 comments · Fixed by #2605
Closed

Bad error message when importing .did that isn't a service #2319

nomeata opened this issue Feb 6, 2021 · 13 comments · Fixed by #2605
Labels
compiler Motoko → Wasm P2 medium priority, resolve within a couple of milestones

Comments

@nomeata
Copy link
Collaborator

nomeata commented Feb 6, 2021

Users out there ran into an exception: https://forum.dfinity.org/t/build-error-with-imported-actor-class/1931

They built a canister using actor class…, which produced this .did:

type anon_class_1_1 = 
 service {
 };
service : () -> anon_class_1_1

which then tripped this code:

    match actor with
    | Some {it=ServT ms; _} ->
       let fs = List.map (check_meth env) ms in
       let fs = M.Env.fold (fun id t fs ->
         match t with
         | M.Con (c, _) -> M.{lab = id; typ = M.Typ c}::fs
         | _ -> assert false) !m_env fs in
       M.Obj (M.Actor, List.sort M.compare_field fs)
    | None -> assert false
    | _ -> assert false 

These assert false should produce more helpful error messages.

(Of course, we also should support importing canister classes, but that's a bigger thing; this issue is just about proper error messages.)

@nomeata
Copy link
Collaborator Author

nomeata commented Feb 6, 2021

@stanleygjones not sure if this is counts as a bugfix (not story-worthy), or if it would constitute a developer-facing improvement worth of a few points.

@crusso
Copy link
Contributor

crusso commented Feb 6, 2021

It's interesting to note that they only reason they were trying to do this is to get access to the installer of an actor, which you can't do except by authoring it as an actor class. Perhaps we should have put the context pattern on the actor keyword after all or expose the primitive for getting access to the installer/caller.

@nomeata
Copy link
Collaborator Author

nomeata commented Feb 6, 2021

Actually, one could argue that this is more an issue for dfx, at least if one follows the philosophy that dfx (by deploying) turns a canister class into a canister instance, and should therefore strip the parameters from the Candid file.

But we should still provide a better error message.

@chenyan-dfinity
Copy link
Contributor

hmm, should this be an error or we can be more permissive that when import canister: for an actor class, it refers to the canister instantiated by the actor class (strip out the init arguments); when import class: for an actor class, it refers to the uninstantiated actor class.

@nomeata
Copy link
Collaborator Author

nomeata commented Feb 6, 2021

That's the pragmatic, non-principled approach ;-)

I think we had that in the thread where we discussed this: conceptually, an IDL for a service instance has no parameters. Whether we strip them in dfx or (implicitly) when parsing is a minor matter of the sort that can cause long and heated debate.

@rossberg
Copy link
Contributor

rossberg commented Feb 8, 2021

Yes, please let's not confuse the domains of X and Y->X, totally different beasts. Even if it seems "pragmatic", I fear it doesn't help users in understanding the difference between the two. And it is likely to get in the way of making actor classes first-class later.

@rossberg rossberg added P2 medium priority, resolve within a couple of milestones compiler Motoko → Wasm labels May 18, 2021
@nomeata
Copy link
Collaborator Author

nomeata commented Jun 12, 2021

People keep running into this (https://forum.dfinity.org/t/motoko-compiler-bug/5095). We should at least produce a helpful error message.

@crusso
Copy link
Contributor

crusso commented Jun 12, 2021

That's weird, I too thought this had been fixed (or, at least, the error improved).

@nomeata
Copy link
Collaborator Author

nomeata commented Jun 12, 2021

Maybe there was a hard fork in the universe's reality?

@chenyan-dfinity
Copy link
Contributor

Weird, I also remember there was a PR to improve the error message....

@crusso
Copy link
Contributor

crusso commented Jun 14, 2021

hmm, should this be an error or we can be more permissive that when import canister: for an actor class, it refers to the canister instantiated by the actor class (strip out the init arguments); when import class: for an actor class, it refers to the uninstantiated actor class.

I'm with @chenyan-dfinity on this one. If the code is written as a class then importing a canister of that class could just strip the argument. We don't support importing of actor classes via import "canister:" and using import "class:" would arguably be more appropriate anyway.

@crusso
Copy link
Contributor

crusso commented Jun 14, 2021

The confusion is already baked into to the language design. A class declaration both names the type of its instances (an actor) and the name of a constructor (a function). Canister import can just be interpreted as importing an actor or instance of a class.

@matthewhammer
Copy link
Contributor

this issue is just about proper error messages.

Reminder.

@nomeata nomeata mentioned this issue Jun 16, 2021
@ggreif ggreif changed the title Bad error message when importing did that isn't a service Bad error message when importing .did that isn't a service Jun 16, 2021
crusso added a commit that referenced this issue Jun 18, 2021
@crusso crusso linked a pull request Jun 21, 2021 that will close this issue
crusso added a commit that referenced this issue Jun 22, 2021
* error, doesn't crash, on import of candid service class
* improve on UnsupportedCandid error reporting, adding source location , error code and message.
mergify bot pushed a commit that referenced this issue Jun 22, 2023
…ng the service arguments. (#4041)

Allow canister imports of service constructors, silently ignoring the service arguments. 

A hack that fixes #3990 (for some definition of fix) and duplicate #2319.

Really, dfx should be feeding the idl of the instantiated service, not service constructor, to dependent canisters, but until it's fixed to do so (and it hasn't been forever now), this is a reasonable and simple workaround, avoiding the error-prone and kludgy workaround of rewriting candid files described, for instance, here:

https://dfinityorg.notion.site/ckBTC-example-Encode-Hackathon-0aaf6292e3404dabb49df5d1b5abc797#08a7469beaf14d6ba35e8827e363e160

and also used here:

https://github.com/letmejustputthishere/ckbtc-payments

via npm scripting hacks (!).

Also see here for the pain this caused:

https://forum.dfinity.org/t/confusing-type-error-when-crossing-canisters-expression-of-type-mytype-cannot-produce-expected-type-mytype-1/20636

UPDATE: I turned the previous error into a warning to nag us to fix dfx.


UPDATE: Potentially obviated by dfinity/sdk#3138, which teaches dfx to strip the service argument.

UPDATE: @chenyan-dfinity thinks we should still merge for other scenarios (old dfx, new compiler, I guess).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler Motoko → Wasm P2 medium priority, resolve within a couple of milestones
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants