-
Notifications
You must be signed in to change notification settings - Fork 25
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
Better errors #51
Better errors #51
Conversation
5e97a76
to
fc5f08f
Compare
Sounds good to me. Judging by opam, there aren't many users of this ilbrary, and the improvement in usability is significant.
Sure. |
b65782a
to
7b99067
Compare
let lexbuf = Lexing.from_string template_data in | ||
let () = | ||
let open Lexing in | ||
lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = template_filename }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this can now be done with just Lexing.set_filename lexbuf template_filename
, but this function only appeared in 4.11 so I just went with the old way.
@@ -1,12 +1,27 @@ | |||
let apply_mustache json_data template_data = | |||
module Mustache = struct |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a Mustache
module where With_locations
is the default. If I remove this declaration, Mustache.parse_lx
and Mustache.render
below will resolve to Mustache.Without_locations
, so the errors will only receive dummy locations. Instead of defining this module, I could instead use Mustache.With_locations.parse_lx
and Mustache.With_locations.render
explicitly -- but I find the global declaration more convenient, as we never want to use the Without_locations
definition in the binary.
(Which reminds me that I need to change the error-printing logic to avoid printing dummy locations. Will do right now.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought our plan was to make good locations the default, in which case this would only be temporary. In any case, it's fine.
7b99067
to
0bd9034
Compare
20abeb6
to
1b08611
Compare
I rebased this PR on top of #55 (cram tests with examples of most error modes). I expected it to be useful for review, but it turns out to be very useful for myself as well, as I immediately spotted several easy improvements I wanted to make to the error messages I had chosen -- applied in the current PR. The error message used the first example now says:
(The change is to use single quotes around variable names; this is not so important with clearly-variable-names like |
- Invalid_template is now properly handled as a parsing error. - The various rendering exceptions are consolidated into a single error type, in preparation for better error payloads.
ae4a590
to
9151d9a
Compare
Before: Line 0, character -1: the variable title is missing. After: (At unknown location): the variable title is missing.
9151d9a
to
fb55977
Compare
CHANGES: * Remove the AST without locations: now all functions build an AST with locations; in particular, parsing always provide located error messages. To ease backward-compatibility, the smart constructors still use the same interface, using dummy locations by default, with a With_locations module for users who wish to explicitly provide locations. (@gasche, rgrinberg/ocaml-mustache#65) * Support for "template inheritance" (partials with parameters) `{{<foo}} {{$param1}}...{{/param1}} {{$param2}}...{{/param2}} {{/foo}` following the widely-implemented semi-official specification mustache/spec#75 (@gasche, 58) * Partials are now supported in the `mustache` command-line tool (@gasche, rgrinberg/ocaml-mustache#57) They are interpreted as template inclusion: "{{>foo/bar}}" will include "foo/bar.mustache", relative to the current working directory. * Improve error messages (@gasche, rgrinberg/ocaml-mustache#47, rgrinberg/ocaml-mustache#51, rgrinberg/ocaml-mustache#56) Note: the exceptions raised by Mustache have changed, this breaks compatibility for users that would catch and deconstruct existing exceptions. * Add `render_buf` to render templates directly to buffers (@gasche, rgrinberg/ocaml-mustache#48) * When a lookup fails in the current context, lookup in parents contexts. This should fix errors when using "{{#foo}}" for a scalar variable 'foo' to check that the variable exists. (@gasche, rgrinberg/ocaml-mustache#49)
CHANGES: * Remove the AST without locations: now all functions build an AST with locations; in particular, parsing always provide located error messages. To ease backward-compatibility, the smart constructors still use the same interface, using dummy locations by default, with a With_locations module for users who wish to explicitly provide locations. (@gasche, rgrinberg/ocaml-mustache#65) * Support for "template inheritance" (partials with parameters) `{{<foo}} {{$param1}}...{{/param1}} {{$param2}}...{{/param2}} {{/foo}` following the widely-implemented semi-official specification mustache/spec#75 (@gasche, 58) * Partials are now supported in the `mustache` command-line tool (@gasche, rgrinberg/ocaml-mustache#57) They are interpreted as template inclusion: "{{>foo/bar}}" will include "foo/bar.mustache", relative to the current working directory. * Improve error messages (@gasche, rgrinberg/ocaml-mustache#47, rgrinberg/ocaml-mustache#51, rgrinberg/ocaml-mustache#56) Note: the exceptions raised by Mustache have changed, this breaks compatibility for users that would catch and deconstruct existing exceptions. * Add `render_buf` to render templates directly to buffers (@gasche, rgrinberg/ocaml-mustache#48) * When a lookup fails in the current context, lookup in parents contexts. This should fix errors when using "{{#foo}}" for a scalar variable 'foo' to check that the variable exists. (@gasche, rgrinberg/ocaml-mustache#49)
CHANGES: * Remove the AST without locations: now all functions build an AST with locations; in particular, parsing always provide located error messages. To ease backward-compatibility, the smart constructors still use the same interface, using dummy locations by default, with a With_locations module for users who wish to explicitly provide locations. (@gasche, rgrinberg/ocaml-mustache#65) * Support for "template inheritance" (partials with parameters) `{{<foo}} {{$param1}}...{{/param1}} {{$param2}}...{{/param2}} {{/foo}` following the widely-implemented semi-official specification mustache/spec#75 (@gasche, 58) * Partials are now supported in the `mustache` command-line tool (@gasche, rgrinberg/ocaml-mustache#57) They are interpreted as template inclusion: "{{>foo/bar}}" will include "foo/bar.mustache", relative to the current working directory. * Improve error messages (@gasche, rgrinberg/ocaml-mustache#47, rgrinberg/ocaml-mustache#51, rgrinberg/ocaml-mustache#56) Note: the exceptions raised by Mustache have changed, this breaks compatibility for users that would catch and deconstruct existing exceptions. * Add `render_buf` to render templates directly to buffers (@gasche, rgrinberg/ocaml-mustache#48) * When a lookup fails in the current context, lookup in parents contexts. This should fix errors when using "{{#foo}}" for a scalar variable 'foo' to check that the variable exists. (@gasche, rgrinberg/ocaml-mustache#49)
CHANGES: * Remove the AST without locations: now all functions build an AST with locations; in particular, parsing always provide located error messages. To ease backward-compatibility, the smart constructors still use the same interface, using dummy locations by default, with a With_locations module for users who wish to explicitly provide locations. (@gasche, rgrinberg/ocaml-mustache#65) * Support for "template inheritance" (partials with parameters) `{{<foo}} {{$param1}}...{{/param1}} {{$param2}}...{{/param2}} {{/foo}` following the widely-implemented semi-official specification mustache/spec#75 (@gasche, 58) * Partials are now supported in the `mustache` command-line tool (@gasche, rgrinberg/ocaml-mustache#57) They are interpreted as template inclusion: "{{>foo/bar}}" will include "foo/bar.mustache", relative to the current working directory. * Improve error messages (@gasche, rgrinberg/ocaml-mustache#47, rgrinberg/ocaml-mustache#51, rgrinberg/ocaml-mustache#56) Note: the exceptions raised by Mustache have changed, this breaks compatibility for users that would catch and deconstruct existing exceptions. * Add `render_buf` to render templates directly to buffers (@gasche, rgrinberg/ocaml-mustache#48) * When a lookup fails in the current context, lookup in parents contexts. This should fix errors when using "{{#foo}}" for a scalar variable 'foo' to check that the variable exists. (@gasche, rgrinberg/ocaml-mustache#49)
CHANGES: * Remove the AST without locations: now all functions build an AST with locations; in particular, parsing always provide located error messages. To ease backward-compatibility, the smart constructors still use the same interface, using dummy locations by default, with a With_locations module for users who wish to explicitly provide locations. (@gasche, rgrinberg/ocaml-mustache#65) * Support for "template inheritance" (partials with parameters) `{{<foo}} {{$param1}}...{{/param1}} {{$param2}}...{{/param2}} {{/foo}` following the widely-implemented semi-official specification mustache/spec#75 (@gasche, 58) * Partials are now supported in the `mustache` command-line tool (@gasche, rgrinberg/ocaml-mustache#57) They are interpreted as template inclusion: "{{>foo/bar}}" will include "foo/bar.mustache", relative to the current working directory. * Improve error messages (@gasche, rgrinberg/ocaml-mustache#47, rgrinberg/ocaml-mustache#51, rgrinberg/ocaml-mustache#56) Note: the exceptions raised by Mustache have changed, this breaks compatibility for users that would catch and deconstruct existing exceptions. * Add `render_buf` to render templates directly to buffers (@gasche, rgrinberg/ocaml-mustache#48) * When a lookup fails in the current context, lookup in parents contexts. This should fix errors when using "{{#foo}}" for a scalar variable 'foo' to check that the variable exists. (@gasche, rgrinberg/ocaml-mustache#49)
This PR is on top of #50, it adds more informative arguments to render-time exceptions and transforms them into better error messages.
Before:
After:
This is a breaking change as the exception types have changed, but the change only affects users who are not catching and inspecting Mustache exceptions.
However, good error locations are only available if people used the
With_locations
modules. If you want a 4.0 release for a breaking change, now may also be a good time to makeWith_locations
the default.(I have some other features planned for the next few days, so I am not suggesting to make a new release right now. But I'm interested in having an idea of the amount of breakage that @rgrinberg would consider acceptable for a future release.)
@rgrinberg I would have liked to add
cram
-style tests for this PR (I'm thinking of havingbin/test
where each error message is tested by cramming the binary), but this requires upgradingdune-lang
to 2.7; I tried this and it complains thataction
was deleted some time ago and I should rewrite some other tests in a way that I don't really understand. When you have time, do you think that you could take care of upgrading dune-lang to 2.x for the project?