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

Manually defined parametric contract throws error: non serializable term error when used without parameters #1460

Open
DrRuhe opened this issue Jul 17, 2023 · 1 comment
Assignees
Labels

Comments

@DrRuhe
Copy link

DrRuhe commented Jul 17, 2023

Describe the bug
Given this Contract that takes a parameter the non-serializable term error will appear pointing to the definition of the contract, which is unrelated to the actual place where the contract is used incorrectly:

let SomeParametricContract = fun parameter label value =>value
in
{
    without_error | SomeParametricContract "param" = {},
    with_error | SomeParametricContract = {},
}
error: non serializable term
  ┌─ assets/fruits.ncl:1:30
  │
1 │ let SomeParametricContract = fun parameter label value =>value
  │                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  │
  = Nickel only supports serlializing to and from strings, booleans, numbers, enum tags, `null` (depending on the format), as well as records and arrays of serializable values.
  = Functions and special values (such as contract labels) aren't serializable.
  = If you want serialization to ignore a specific value, please use the `not_exported` metadata.

Expected behavior
Instead of throwing an unrelated non-serializable term error, the CLI should report something like this:

error: invalid contract
  ┌─ assets/fruits.ncl:1:30
  │
5 │with_error | SomeParametricContract = {},
  │             ^^^^^^^^^^^^^^^^^^^^^^
  │
  = Note: are you missing a parameter?
@yannham yannham added P1 critical: next release area: contracts area: error messages P2 major: an upcoming release and removed P1 critical: next release labels Jul 20, 2023
@yannham
Copy link
Member

yannham commented Jul 20, 2023

Hi, thank for reporting! I concur that this is not a rare error to make, and the message is not helping.

I currently don't have a good rationale to throw an error though, we'll have to think about it more. What happens is that a contract annotation like this ends up as something like with_error = SomeParametricContract label {}, which is indeed still a function that is not serializable. The issue is that we can't just error out when a contract application evaluates to a function: typically, a function contract like f | Number -> String turns into $arrow $number $string f, and should evaluate to a function (a version of f wrapped with additional checks).

Maybe we can backtrack on such a non-serializable error and check this case in an ad-hoc way (does the problematic value have a contract attached).

Another improvement, independently from this contract error, should be to show which field was being evaluated/serialized when the error occurred; that would at least give a minimum amount of error locality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants