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

config: Pretty print yaml parser errors #86

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

yhabteab
Copy link
Member

The PrettyPrint() method of the yaml errors doesn't get triggered automatically, so we've to do it via the yaml.FormatError() helper function. This will return the prettified string of the provided error, if it implements the yaml.errors#PrettyPrinter interface, otherwise just the error string.

Before

~/Workspace/go/icingadb (main ✗) go run cmd/icingadb/main.go --config config.example.yml
can't parse YAML file config.example.yml: cannot unmarshal -1 into Go value of type uint16 ( overflow )
exit status 1

After

Bildschirmfoto 2024-10-30 um 09 42 27

resolves Icinga/icingadb#755

The `PrettyPrint()` method of the yaml errors doesn't get triggered
automatically, so we've to do it via the `yaml.FormatError()` helper
function. This will return the prettified string of the provided error,
if it implements the `yaml.errors#PrettyPrinter` interface, otherwise
just the error string.
@yhabteab yhabteab added the enhancement New feature or request label Oct 30, 2024
@yhabteab yhabteab added this to the 0.4.0 milestone Oct 30, 2024
@yhabteab yhabteab requested a review from oxzi October 30, 2024 08:43
@cla-bot cla-bot bot added the cla/signed CLA is signed by all contributors of a PR label Oct 30, 2024
@lippserd
Copy link
Member

The PrettyPrint() method of the yaml errors doesn't get triggered automatically

Why? I would rather not try to fix it here but in Icinga DB where we just do fmt.Fprintln(os.Stderr, err).

@yhabteab
Copy link
Member Author

The PrettyPrint() method of the yaml errors doesn't get triggered automatically

Why?

It is not a standard GO interface, none of the fmt.Print* methods are going to call it and that is exactly what yaml.FormatError is for.

I would rather not try to fix it here but in Icinga DB where we just do fmt.Fprintln(os.Stderr, err).

This library is used by more than 1 project already and you want to do this in each one of them? Btw. Icinga DB uses not just fmt.Fprintln(os.Stderr, err) but utils.PrintErrorThenExit() helper function of this library.

@julianbrost
Copy link
Contributor

The PrettyPrint() method of the yaml errors doesn't get triggered automatically

Why?

It is not a standard GO interface, none of the fmt.Print* methods are going to call it and that is exactly what yaml.FormatError is for.

I believe I've seen these pretty-printed YAML errors before1 and can't remember that we manually used yaml.FormatError() before. Is there any chance that the error returned by the YAML library implements the fmt.Stringer or fmt.Formatter interfaces which gets lost by wrapping the error?

Footnotes

  1. There's a slight possibility that this could have been before we switched YAML parser implementation.

@lippserd
Copy link
Member

This library is used by more than 1 project already and you want to do this in each one of them? Btw. Icinga DB uses not just fmt.Fprintln(os.Stderr, err) but utils.PrintErrorThenExit() helper function of this library.

Yes, FromYAMLFile() does not decide how to print errors. Especially not, whether the output is colored. I'm open to support this in a utility function though. But I think we need to detect whether we're actually running in a terminal that supports colors. (Or just not color it at all.). Or we return a wrapped error that is actually pretty printable by standard Go utility.

@yhabteab
Copy link
Member Author

I believe I've seen these pretty-printed YAML errors before1 and can't remember that we manually used yaml.FormatError() before.

The Error() method of the syntax errors returns the prettified string, but not e.g. type errors.

Syntax error:

can't parse YAML file config.example.yml: [12:3] unknown field "hosts"
   9 | #  type: mysql
  10 | 
  11 |   # Database host or absolute Unix socket path.
> 12 |   hosts: localhost
         ^
  14 |   # Database port. By default, the MySQL or PostgreSQL port, depending on the database type.
  15 | #  port:
  16 | 
exit status 1

type error:

can't parse YAML file config.example.yml: cannot unmarshal string into Go struct field Config.Retention of type uint16
exit status 1

Is there any chance that the error returned by the YAML library implements the fmt.Stringer or fmt.Formatter interfaces which gets lost by wrapping the error?

No, none of the errors implement such an interface.

@lippserd
Copy link
Member

lippserd commented Oct 30, 2024

The Error() method of the syntax errors returns the prettified string, but not e.g. type errors.

Why don't we fix it in the lib and submit a PR? I would actually introduce implementing fmt.Formatter then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla/signed CLA is signed by all contributors of a PR enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Retention Count config uint64 overflow
3 participants