Skip to content

Commit

Permalink
avoid issues when handling errors
Browse files Browse the repository at this point in the history
- external errors should be checked with errors.Is
- external errors should be compared with errors.As
- errors should be wrapped with %w in fmt.Errorf
  • Loading branch information
ccoVeille committed Apr 5, 2024
1 parent 976241f commit 4f548c3
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 26 deletions.
7 changes: 4 additions & 3 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,9 @@ func (cli *cli) process(iter inputIter, code *gojq.Code) error {
continue
}
if e := cli.printValues(code.Run(v, cli.argvalues...)); e != nil {
if e, ok := e.(*gojq.HaltError); ok {
if v := e.Value(); v != nil {
var haltErr *gojq.HaltError
if errors.As(e, &haltErr) {
if v := haltErr.Value(); v != nil {
if str, ok := v.(string); ok {
cli.errStream.Write([]byte(str))
} else {
Expand All @@ -343,7 +344,7 @@ func (cli *cli) process(iter inputIter, code *gojq.Code) error {
cli.errStream.Write([]byte{'\n'})
}
}
err = e
err = haltErr
break
}
fmt.Fprintf(cli.errStream, "%s: %s\n", name, e)
Expand Down
7 changes: 4 additions & 3 deletions cli/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@ type jsonParseError struct {

func (err *jsonParseError) Error() string {
var offset int
if err.err == io.ErrUnexpectedEOF {
var syntaxErr *json.SyntaxError
if errors.Is(err.err, io.ErrUnexpectedEOF) {
offset = len(err.contents) + 1
} else if e, ok := err.err.(*json.SyntaxError); ok {
offset = int(e.Offset)
} else if errors.As(err.err, &syntaxErr) {
offset = int(syntaxErr.Offset)
}
linestr, line, column := getLineByOffset(err.contents, offset)
if line += err.line; line > 1 {
Expand Down
21 changes: 12 additions & 9 deletions cli/inputs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"bytes"
"encoding/json"
"errors"
"io"
"os"
"strings"
Expand Down Expand Up @@ -89,15 +90,16 @@ func (i *jsonInputIter) Next() (any, bool) {
}
var v any
if err := i.dec.Decode(&v); err != nil {
if err == io.EOF {
if errors.Is(err, io.EOF) {
i.err = err
return nil, false
}
var offset *int64
var line *int
if err, ok := err.(*json.SyntaxError); ok {
err.Offset -= i.offset
offset, line = &err.Offset, &i.line
var syntaxErr *json.SyntaxError
if errors.As(err, &syntaxErr) {
syntaxErr.Offset -= i.offset
offset, line = &syntaxErr.Offset, &i.line
}
i.err = &jsonParseError{i.fname, i.ir.getContents(offset, line), i.line, err}
return i.err, true
Expand Down Expand Up @@ -275,15 +277,16 @@ func (i *streamInputIter) Next() (any, bool) {
}
v, err := i.stream.next()
if err != nil {
if err == io.EOF {
if errors.Is(err, io.EOF) {
i.err = err
return nil, false
}
var offset *int64
var line *int
if err, ok := err.(*json.SyntaxError); ok {
err.Offset -= i.offset
offset, line = &err.Offset, &i.line
var syntaxErr *json.SyntaxError
if errors.As(err, &syntaxErr) {
syntaxErr.Offset -= i.offset
offset, line = &syntaxErr.Offset, &i.line
}
i.err = &jsonParseError{i.fname, i.ir.getContents(offset, line), i.line, err}
return i.err, true
Expand Down Expand Up @@ -324,7 +327,7 @@ func (i *yamlInputIter) Next() (any, bool) {
}
var v any
if err := i.dec.Decode(&v); err != nil {
if err == io.EOF {
if errors.Is(err, io.EOF) {
i.err = err
return nil, false
}
Expand Down
3 changes: 2 additions & 1 deletion cli/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cli

import (
"encoding/json"
"errors"
"io"
)

Expand Down Expand Up @@ -47,7 +48,7 @@ func (s *jsonStream) next() (any, error) {
for {
token, err := s.dec.Token()
if err != nil {
if err == io.EOF && s.states[len(s.states)-1] != jsonStateTopValue {
if errors.Is(err, io.EOF) && s.states[len(s.states)-1] != jsonStateTopValue {
err = io.ErrUnexpectedEOF
}
return nil, err
Expand Down
20 changes: 13 additions & 7 deletions execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gojq

import (
"context"
"errors"
"math"
"reflect"
"sort"
Expand Down Expand Up @@ -88,15 +89,19 @@ loop:
if err == nil {
break loop
}
switch e := err.(type) {
case *tryEndError:
err = e.err
var tryEndErr *tryEndError
var breakErr *breakError
var haltErr *HaltError
var valueErr ValueError
switch {
case errors.As(err, &tryEndErr):
err = tryEndErr.err
break loop
case *breakError, *HaltError:
case errors.As(err, &breakErr), errors.As(err, &haltErr):
break loop
case ValueError:
case errors.As(err, &valueErr):
env.pop()
env.push(e.Value())
env.push(valueErr.Value())
default:
env.pop()
env.push(err.Error())
Expand Down Expand Up @@ -125,7 +130,8 @@ loop:
case opforklabel:
if backtrack {
label := env.pop()
if e, ok := err.(*breakError); ok && e.v == label {
var breakErr *breakError
if errors.As(err, &breakErr) && breakErr.v == label {
err = nil
}
break loop
Expand Down
4 changes: 2 additions & 2 deletions func.go
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ func funcFromJSON(v any) any {
if err := dec.Decode(&w); err != nil {
return &func0WrapError{"fromjson", v, err}
}
if _, err := dec.Token(); err != io.EOF {
if _, err := dec.Token(); !errors.Is(err, io.EOF) {
return &func0TypeError{"fromjson", v}
}
return normalizeNumbers(w)
Expand Down Expand Up @@ -2065,7 +2065,7 @@ func compileRegexp(re, flags string) (*regexp.Regexp, error) {
}
r, err := regexp.Compile(re)
if err != nil {
return nil, fmt.Errorf("invalid regular expression %q: %s", re, err)
return nil, fmt.Errorf("invalid regular expression %q: %w", re, err)
}
return r, nil
}
Expand Down
3 changes: 2 additions & 1 deletion module_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gojq

import (
"encoding/json"
"errors"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -98,7 +99,7 @@ func (l *moduleLoader) LoadJSONWithMeta(name string, meta map[string]any) (any,
for {
var val any
if err := dec.Decode(&val); err != nil {
if err == io.EOF {
if errors.Is(err, io.EOF) {
break
}
if _, err := f.Seek(0, io.SeekStart); err != nil {
Expand Down

0 comments on commit 4f548c3

Please sign in to comment.