-
Notifications
You must be signed in to change notification settings - Fork 831
Potential changes to nom error handling story for 6.0 #1136
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
Comments
good idea
what would that type do?
this might be an issue: if people use error types provided by nom (most of them will), they won't be able to provide
will do
carrying a reference to the input is useful for parsers, and passing the original input when processing the error will not always work: some libraries us as input type a wrapper that counts lines and provides user friendly spans. Maybe the error could be converted to a
For parser generators, a parse error will generally have all of the information because it knows exactly how it got there, but for parser combinators like nom, a parser will not know why it has been called (like, a function name parser could be used when parsing its declaration, or in an expression). That's why I added that "stacktrace" for parsers, to pattern match on it. In most cases it is not needed, but for programming languages it's hard to have proper errors without the context. Side note: nom's
especially considering that parts of |
Gonna reply to these comments when I'm at my computer but I just wanted to drop this link in and another possible idea http://sled.rs/errors Use Result<Result<T, Nonterminal error>, TerminalError> instead of nom::Error to represent multiple error channelsThe API grossness might be worse than the current state but I've been trying to figure out how to support a tristate Try type for weeks now and this blog post was the first one that really seems like a good fit to me |
Not within rust afaik, but I think haskell might use if more commonly.
I'm mostly worried about coherence, but also it would be a nice to have to impl Error i think, and it might also be helpful for doing the 'a -> 'static conversion for working with error reporters.
The error types provided by nom might be able to implement the current discard behavior as part of their api, where a From<E: Error> just discards the error and becomes We might be able to do some cheeky stuff with
Oh, yea I didn't mean get rid of the context, I just want to change how nom models context, I am convinced we can have all the same behavior and 🤞 the same performance characteristics while also keeping accumulated errors and accumulated context separate.
I think it might work, if you want we can probably test it out, nika and I have a proof of concept for the error member access that doesn't go thru |
I just checked, and... yes 😭 |
I'm so sorry, feel free to assign error handling issues to me btw, I'd like to help out but I'm bad at staying organized or prioritizing things well. |
If you wouldn't mind my adding my own two cents here, I would welcome an overhaul of the error handling. This is partially because the ParseError trait isn't very useful - there's no way to convert it to a std::Error, and because it's a trait, it's difficult to put into my own error types. Instead I'm hardcoding my errors to do a clumsy mapping between If there's a better way to interoperate with |
I'm a bit new to rust, but I'd love to help on this issue. I've been using nom to write a parser for a compiler I've been building. @yaahc has mentioned that she will mentor. If that's ok, I'll probably need a few days to start understanding all the issues and then maybe try a few small PRs. I'll likely have a lot of questions. |
@yaahc did anything interesting change in the error handling space in the past months? I'm planning to finish this release soon, so if some new ideas came, I could implement them right away |
Not really anything new to report. I am going to be starting up a error handling project group soon so we will hopefully start getting more work done but it will mostly be work on stabilizing what we already have and consolidating the ecosystem a bit better. The ideas in this issue are still applicable IMO, so if you wanna try implementing any of them for this release that would be good but I think its also okay if you punt on it. |
so, on the plus side: changing the But changing the result type to |
😬 indeed |
If I may add my two cents to this issue... |
so, here are th recent changes around error handling:
@thirtythreeforty what ind of integration do you have in mind, and why are you trying to add the @torokati44 you might need a custom error type with a wrapper combinator you insert here and there for that, because recording errors for |
My understanding of ParseError is that it's the "generic" supertype of all the actual error types. I thought the point of it was to use ParseError wherever possible (even in my own combinators) so it was possible to switch between Error and VerboseError with a cargo flag or similar. It turned out that I didn't end up using it because it proved difficult. The changes you describe will really help though. |
with af7d8fe custom error types will now be able to store the error from |
@thirtythreeforty being able to switch between error types would only be useful if you make a library of combinators, otherwise you should directly use a single error type. If you want to switch with a flag, it would be easier to have a custom error type, and have its content and |
@Geal out of curiosity, why did you add a |
The error type will also get the input position and an |
That or if instead of using a tuple you provided a type for bundling these you could do something like
|
At least, ostensibly; none of the implementations that nom ships (as of nom 5 and nom 6-alpha1) do anything with |
I haven't tested this stuff out yet so I'm not sure how feasible any of it is but here are the ideas I think are worth investigating for 6.0:
Move off of
nom::error::ParseError
and usestd::error::Error
insteadappend
andadd_context
combinators that need to merge errors can instead usestd::ops::Add
(remove ParseError::add_context #1131).append
andor
is in practice, so this may instead apply toor
.From
instead offrom_error_kind
for converting from a root cause error to a user provided error type(I, ErrorKind)
tuple.Inter-operate with foreign error types instead of discarding
map_res
to try to useFrom
into the user Error type from the error type of the closure, specifically make sure to support preserving std ParseIntError and similar errorsverify
to work withResult
instead ofbool
to allow custom error messages upon verify failures.Look into interoperating with error reporting mechanisms that require
'static
Probably with the
ToOwned
trait in std, I'm not sure how easy it would be to write the impl for this as a user in practice.Alternatively: we can look into removing the lifetime bound on errors that keep the input with them, my understanding is that the main reason that these carry around references is to do offsets against the original reference, we could instead carry a ptr and require that the original reference is provided when printing the final error report to get the nicely rendered contexts.
Stop treating context as Errors
The specific location in a program / context of what it was doing is not an error, or indicative of a failure, and I don't think it should be stored in the error chain/tree the same way the various parse failures are. Instead I'd like to see it gathered in a similar way to how I'm proposing we support
Error Return Traces
Additional Comments
I'm not positive is now is the best time to apply these changes. I'm currently working on this RFC rust-lang/rfcs#2895 to add a way to get custom context out of dyn Errors, and a few of the changes I'm imagining would probably want to use this functionality as part of the error reporting mechanism, though it gets a little hairy because nom errors like to have references in them, and the context extraction mechanisms would work for any members with lifetimes in them...
The vague idea im throwing around in my head is something like this.
This would hopefully support printing all these errors
The specific syntax and error report shape are not really the point here, this would probably need a lot of tweeking, but hopefully this gets the idea across.
The text was updated successfully, but these errors were encountered: