-
Notifications
You must be signed in to change notification settings - Fork 271
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
feat: Display schema parse errors. #136
Conversation
We can possibly iterate on this if / when we have a display impl for apollo_parser::Error, but this would be a nice first step for us to be able to work on supported features with users. |
#[derive(Debug, Error)] | ||
pub enum SchemaError { | ||
/// IO error: {0} | ||
#[error("IO error: {0}")] | ||
IoError(#[from] std::io::Error), | ||
/// Parsing error(s). | ||
#[error("parse errors {0:#?}")] |
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.
Keep using Display as it provides the doc at the same time than the error message
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.
the parser errors don't expose any impl display, do you want me to build an impl display for ParseErrors ?
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.
no I meant displaydoc::Display
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.
But eventually parse errors should implement Display indeed. Just not in this repository
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.
Oh I see, thanks for clearing it up!
since the error has span information, could we get the context too? Like https://github.com/zkat/miette |
@Geal @cecton This sounds like good ideas! CCing @lrlna because I think they have something else in mind since the members are pub(crate) and there is no impl Display or Error. |
I haven't yet implemented display for errors, but I was going to use miette. Might be able to get you something workable this week! |
Super cool, marking this as draft, until we can do it right! Thanks again for your feedback @lrlna 🚀 |
With the previous apollo-rs dependency bump, we are now able to provide a bit more context and details when a schema parse failed. This commit displays the schema errors that have been noticed during parsing.
7da9988
to
00b82a3
Compare
…e, which is targeted by RUSTSEC-2020-0071
span: SourceSpan, | ||
} | ||
|
||
impl std::fmt::Display for ParseErrors { |
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.
Super cool PR!
Though I'm not sure you are handling this properly. This diagnostic library inserts colors to the terminal. This is fine in the terminal but not so great for the logs in a text file. I believe Display
should still be free of any ansi codes and stuff.
What I would suggest is:
- move this code to its own function: rename
fmt()
toprint_pretty()
or something - it doesn't need to take the formatter in argument, you can use stdout or stderr directly (the formatter is a requirement for Display but here we know that the output will has to be the tty)
- You will need to change the main.rs to inspect the error you return and do a special handling for SchemaError::Parse
I know this sounds a lot more complicated but it will be more correct. The risk here is to sending logs with ansi codes somewhere by mistake.
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.
Hmm so what you mean is that we're conflating Error propagation and reporting, which is very true!
I wonder what responsibility should lie within Display
and to the std::fmt::formatter. I would for example have liked to be able to ask the formatter if it supports colors.
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.
There might be a couple of clues https://docs.rs/miette/3.2.0/miette/trait.ReportHandler.html around here, I'll let you know what I've found!
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 would for example have liked to be able to ask the formatter if it supports colors.
afaik this is unsupported. That is why I think you can't put ansi code in implementations of Debug and Display.
For example ToString depends on Display. Is a string supposed to have ansi codes like that?
But then really my concern is that we report errors through other channels (journald, syslog, etc...) and we incorrectly send ansi codes in them.
Again this is all fancy but we should make it clear that this targets only the terminal (aka stdout or stderr if and only if it is a tty, otherwise you need to strip the ansi codes).
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.
ohhh i did not know this is how you were going to send the error to the logs! I think the logs should just get the error slice, nothing should be formatted at all! Whatever reads the logs can do the formatting, or you can pipe the logs to a formatter.
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.
Well it's in flux really, We do show the logs to a console at the moment, so we might as well have nice ones. OTOH we do have log exporters as well, so I'll probably move the formating to the "console logging layer", I feel this is what @cecton is hinting at?
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.
To be sure we understand each other:
-
Remove the
{0}
from the doc comment which will prevent this enum's Display to use the Display impl of ParseErrors. If the error gets logged, the user will have no other message than "Parsing error(s).". This is fine./// Parsing error(s). Parse(ParseErrors),
-
Change this piece of code:
impl std::fmt::Display for ParseErrors { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // ... } }
To this:
impl ParseErrors { fn print_pretty(&self) { // ... also replace writeln!(f, ...) by eprintln!(...) } }
So we don't end up with a Display implementation and a ToString implementation that renders ansi codes (things like this
ESC[38;5;
in the string. See ANSI escape codes). -
In
crates/apollo-router-core/src/schema.rs
, instead of just simply returning the error, use yourprint_pretty
function:if !tree.errors().is_empty() { let err = SchemaError::from_parse_errors( s.to_string(), tree.errors().to_vec(), ); if isatty() { err.print_pretty(); } return Err(err);
You'll need this: isatty
marking it as draft, until errors return an iterator |
I'm unsubscribing for now. Ping me when you need a review again. |
This input: schema
@core(feature: "https://specs.apollo.dev/core/v0.1"),
@core(feature: "https://specs.apollo.dev/join/v0.1")
{
query: Query
mutation: Mutation
}
directive @core(feature: String!) repeatable on SCHEMA
thisdoesntbelonghere
directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet) on FIELD_DEFINITION generates this output in a TTY: and this output if not in a TTY:
I think this can be refactored and then reviewed. |
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.
Awesomely simple 👏
# [v0.1.0-alpha.3] 2022-01-11 ## 🚀🌒 Public alpha release > An alpha or beta release is in volatile, active development. The release might not be feature-complete, and breaking API changes are possible between individual versions. ## ✨ Features - Trace sampling [#228](#228): Tracing each request can be expensive. The router now supports sampling, which allows us to only send a fraction of the received requests. - Health check [#54](#54) ## 🐛 Fixes - Schema parse errors [#136](#136): The router wouldn't display what went wrong when parsing an invalid Schema. It now displays exactly where a the parsing error occurred, and why. - Various tracing and telemetry fixes [#237](#237): The router wouldn't display what went wrong when parsing an invalid Schema. It now displays exactly where a the parsing error occurred, and why. - Query variables validation [#62](#62): Now that we have a schema parsing feature, we can validate the variables and their types against the schemas and queries.
fixes #182
With the previous apollo-rs dependency bump, we are now able to provide a bit more context and details when a schema parse failed.
This commit displays the schema errors that have been noticed during parsing.