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

Structured parse errors #489

Closed
jparise opened this issue Jun 5, 2021 · 1 comment · Fixed by #492
Closed

Structured parse errors #489

jparise opened this issue Jun 5, 2021 · 1 comment · Fixed by #492

Comments

@jparise
Copy link
Contributor

jparise commented Jun 5, 2021

idl.Parse() errors are always of the un-exported type idl.internal.parseError, which wraps a map of per-line parse error messages.

type parseError struct {
	Errors map[int][]string
}

It would be useful to expose these per-line error messages to the caller in a structured way. Otherwise, the only visibility callers have into parse errors is the multiline string provided by parseError.Error():

func (pe parseError) Error() string {
	var buffer bytes.Buffer
	buffer.WriteString("parse error\n")
	for line, msgs := range pe.Errors {
		for _, msg := range msgs {
			buffer.WriteString(fmt.Sprintf("  line %d: %s\n", line, msg))
		}
	}
	return buffer.String()
}
@abhinav
Copy link
Contributor

abhinav commented Jun 7, 2021

Yeah, the error reporting is really old. I'm in favor of exposing this information. Perhaps something like this:

package idl

type ParseError struct{ Lines []LineError }

type LineError struct {
  Line int
  Err  error
}

It's been a while, but looking at lex.rl, what this will take modifying the following:

func (lex *lexer) Error(e string) {

To something like this:

func (lex *lexer) AppendError(err error)  {
  lex.parseFailed = true
  lex.errors = append(lex.errors, LineError{Line: lex.line, Err: err}
}

And updating all the call sites to it:

-lex.Error(err.Error())
+lex.AppendError(err)

If we define ParseError and LineError in idl/internal, then we'll need to export non-internal versions of them from the idl package. I'd like to avoid type ParseError = internal.ParseError because I think that that hurts documentation and discoverability, so maybe we'd have to re-define them in idl and map the internal.ParseError to the non-internal variants.

abhinav pushed a commit that referenced this issue Jun 9, 2021
Previously, parse errors (`idl.internal.parseError`) weren't visible to
`idl.Parse()`'s callers. This was inconvenient because it's useful to have
access to (a) the full list of parse errors and (b) the line number that
caused each parse error.

This change introduces `idl.ParseError` which provides a list of errors
and their lines.

Fixes #489
abhinav pushed a commit that referenced this issue Jul 23, 2021
Previously, parse errors (`idl.internal.parseError`) weren't visible to
`idl.Parse()`'s callers. This was inconvenient because it's useful to have
access to (a) the full list of parse errors and (b) the line number that
caused each parse error.

This change introduces `idl.ParseError` which provides a list of errors
and their lines.

Fixes #489
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants