PopulateErrorDetails properly wraps the "last error" field in the lexer.
( tokID int32, lastTokStr string, lastTokPos int32, lastErr error, lIn string, )
| 419 | |
| 420 | // PopulateErrorDetails properly wraps the "last error" field in the lexer. |
| 421 | func PopulateErrorDetails( |
| 422 | tokID int32, lastTokStr string, lastTokPos int32, lastErr error, lIn string, |
| 423 | ) error { |
| 424 | var retErr error |
| 425 | |
| 426 | if tokID == ERROR { |
| 427 | // This is a tokenizer (lexical) error: the scanner |
| 428 | // will have stored the error message in the string field. |
| 429 | err := pgerror.WithCandidateCode(errors.Newf("lexical error: %s", lastTokStr), pgcode.Syntax) |
| 430 | retErr = errors.WithSecondaryError(err, lastErr) |
| 431 | } else { |
| 432 | // This is a contextual error. Print the provided error message |
| 433 | // and the error context. |
| 434 | if !strings.Contains(lastErr.Error(), "syntax error") { |
| 435 | // "syntax error" is already prepended when the yacc-generated |
| 436 | // parser encounters a parsing error. |
| 437 | lastErr = errors.Wrap(lastErr, "syntax error") |
| 438 | } |
| 439 | retErr = errors.Wrapf(lastErr, "at or near \"%s\"", lastTokStr) |
| 440 | } |
| 441 | |
| 442 | // Find the end of the line containing the last token. |
| 443 | i := strings.IndexByte(lIn[lastTokPos:], '\n') |
| 444 | if i == -1 { |
| 445 | i = len(lIn) |
| 446 | } else { |
| 447 | i += int(lastTokPos) |
| 448 | } |
| 449 | // Find the beginning of the line containing the last token. Note that |
| 450 | // LastIndexByte returns -1 if '\n' could not be found. |
| 451 | j := strings.LastIndexByte(lIn[:lastTokPos], '\n') + 1 |
| 452 | // Output everything up to and including the line containing the last token. |
| 453 | var buf bytes.Buffer |
| 454 | fmt.Fprintf(&buf, "source SQL:\n%s\n", lIn[:i]) |
| 455 | // Output a caret indicating where the last token starts. |
| 456 | fmt.Fprintf(&buf, "%s^", strings.Repeat(" ", int(lastTokPos)-j)) |
| 457 | return errors.WithDetail(retErr, buf.String()) |
| 458 | } |
| 459 | |
| 460 | func (l *lexer) populateErrorDetails() { |
| 461 | lastTok := l.lastToken() |
no test coverage detected
searching dependent graphs…