better error messages for YAML

Hello cafe, I have a bit of a conundrum here. The situation is such that I'm using the YAML package to parse YAML configuration files; some of the values in the file format require further parsing (using my own ginger library), and all that works fine. One problem though; since this is aimed at end users, I want to preset error messages that pinpoint the exact error location in case the ginger parse fails. However, the ginger parser doesn't get to see the entire YAML source, because it runs on just an individual string value inside the YAML, and the YAML parser itself doesn't report source positions either. The unfortunate result is that while I get "technically correct" parser errors from Ginger, the source positions they report are relative to the string value, i.e., all errors are reported as being on line 1 of an unnamed source file. The relevant code is here: https://github.com/tdammers/sprinkles/blob/master/src/Web/Sprinkles/Replacem... The only solution I can think of right now involves writing my own YAML parser, and probably also an Aeson drop-in replacement; I don't really want to do that though. Is there any other way to get what I want? -- Tobias Dammers - tdammers@gmail.com

The Text.Libyaml[1] module provides a streaming interface, which allows
more flexibility and doesn't jump through the aeson Value type at all.
Currently, it doesn't include location information, but I _think_ the
underlying libyaml C library makes that information available. I'd
certainly be open to a PR to add something like:
decodeWithPosition :: ByteString -> Producer m (Event, Position)
And that way you don't have to rewrite a parser or the FFI bindings.
[1] https://www.stackage.org/haddock/lts-7.7/yaml-0.8.20/Text-Libyaml.html
On Thu, Nov 3, 2016 at 11:47 AM, Tobias Dammers
Hello cafe,
I have a bit of a conundrum here.
The situation is such that I'm using the YAML package to parse YAML configuration files; some of the values in the file format require further parsing (using my own ginger library), and all that works fine.
One problem though; since this is aimed at end users, I want to preset error messages that pinpoint the exact error location in case the ginger parse fails. However, the ginger parser doesn't get to see the entire YAML source, because it runs on just an individual string value inside the YAML, and the YAML parser itself doesn't report source positions either. The unfortunate result is that while I get "technically correct" parser errors from Ginger, the source positions they report are relative to the string value, i.e., all errors are reported as being on line 1 of an unnamed source file.
The relevant code is here:
https://github.com/tdammers/sprinkles/blob/master/src/Web/ Sprinkles/Replacement.hs#L40
The only solution I can think of right now involves writing my own YAML parser, and probably also an Aeson drop-in replacement; I don't really want to do that though.
Is there any other way to get what I want?
-- Tobias Dammers - tdammers@gmail.com _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

For aeson there is a > combinator in an "internal" modue lfor adding
custom error messages (https://github.com/bos/aeson/issues/475). There's
definitely room for improving error messages though, I hope you'd consider
helping out with that in aeson rather than rolling your own :)
But what Michael says makes a lot of sense, going through aeson is not
optimal. Especially since yaml is a superset (in terms of constructs) of
json.
- Adam
On Thu, Nov 3, 2016 at 10:55 AM Michael Snoyman
The Text.Libyaml[1] module provides a streaming interface, which allows more flexibility and doesn't jump through the aeson Value type at all. Currently, it doesn't include location information, but I _think_ the underlying libyaml C library makes that information available. I'd certainly be open to a PR to add something like:
decodeWithPosition :: ByteString -> Producer m (Event, Position)
And that way you don't have to rewrite a parser or the FFI bindings.
[1] https://www.stackage.org/haddock/lts-7.7/yaml-0.8.20/Text-Libyaml.html
On Thu, Nov 3, 2016 at 11:47 AM, Tobias Dammers
wrote: Hello cafe,
I have a bit of a conundrum here.
The situation is such that I'm using the YAML package to parse YAML configuration files; some of the values in the file format require further parsing (using my own ginger library), and all that works fine.
One problem though; since this is aimed at end users, I want to preset error messages that pinpoint the exact error location in case the ginger parse fails. However, the ginger parser doesn't get to see the entire YAML source, because it runs on just an individual string value inside the YAML, and the YAML parser itself doesn't report source positions either. The unfortunate result is that while I get "technically correct" parser errors from Ginger, the source positions they report are relative to the string value, i.e., all errors are reported as being on line 1 of an unnamed source file.
The relevant code is here:
https://github.com/tdammers/sprinkles/blob/master/src/Web/Sprinkles/Replacem...
The only solution I can think of right now involves writing my own YAML parser, and probably also an Aeson drop-in replacement; I don't really want to do that though.
Is there any other way to get what I want?
-- Tobias Dammers - tdammers@gmail.com _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
participants (3)
-
Adam Bergmark
-
Michael Snoyman
-
Tobias Dammers