Skip to content

Commit bbbbe84

Browse files
committed
export HaltError struct type not interface
1 parent c8171c6 commit bbbbe84

File tree

6 files changed

+20
-30
lines changed

6 files changed

+20
-30
lines changed

README.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,7 @@ func main() {
116116
break
117117
}
118118
if err, ok := v.(error); ok {
119-
if err, ok := err.(gojq.HaltError); ok {
120-
if err.Value() != nil {
121-
log.Fatalln(err)
122-
}
119+
if err, ok := err.(*gojq.HaltError); ok && err.Value() == nil {
123120
break
124121
}
125122
log.Fatalln(err)
@@ -137,8 +134,8 @@ func main() {
137134
- In either case, you cannot use custom type values as the query input. The type should be `[]any` for an array and `map[string]any` for a map (just like decoded to an `any` using the [encoding/json](https://golang.org/pkg/encoding/json/) package). You can't use `[]int` or `map[string]string`, for example. If you want to query your custom struct, marshal to JSON, unmarshal to `any` and use it as the query input.
138135
- Thirdly, iterate through the results using [`iter.Next() (any, bool)`](https://pkg.go.dev/github.com/itchyny/gojq#Iter). The iterator can emit an error so make sure to handle it. The method returns `true` with results, and `false` when the iterator terminates.
139136
- The return type is not `(any, error)` because the iterator may emit multiple errors. The `jq` and `gojq` commands stop the iteration on the first error, but the library user can choose to stop the iteration on errors, or to continue until it terminates.
140-
- In any case, it is recommended to stop the iteration on [`HaltError`](https://pkg.go.dev/github.com/itchyny/gojq#HaltError), which is emitted on `halt` and `halt_error` functions, although these functions are not commonly used.
141-
If the error value of `HaltError` is `nil`, stop the iteration without handling the error.
137+
- In any case, it is recommended to stop the iteration on [`gojq.HaltError`](https://pkg.go.dev/github.com/itchyny/gojq#HaltError), which is emitted by `halt` and `halt_error` functions, although these functions are rarely used.
138+
The error implements [`gojq.ValueError`](https://pkg.go.dev/github.com/itchyny/gojq#ValueError), and if the error value is `nil`, stop the iteration without handling the error.
142139
Technically speaking, we can fix the iterator to terminate on the halting error, but it does not terminate at the moment.
143140
The `halt` function in jq not only stops the iteration, but also terminates the command execution, even if there are still input values.
144141
So, gojq leaves it up to the library user how to handle the halting error.

cli/cli.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ func (cli *cli) process(iter inputIter, code *gojq.Code) error {
333333
continue
334334
}
335335
if e := cli.printValues(code.Run(v, cli.argvalues...)); e != nil {
336-
if e, ok := e.(gojq.HaltError); ok {
336+
if e, ok := e.(*gojq.HaltError); ok {
337337
if v := e.Value(); v != nil {
338338
if str, ok := v.(string); ok {
339339
cli.errStream.Write([]byte(str))

error.go

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,6 @@ type ValueError interface {
1111
Value() any
1212
}
1313

14-
// HaltError is an interface for errors of halt and halt_error functions.
15-
// Any HaltError is [ValueError], and if the value is nil, discard the
16-
// error and stop the iteration. Consider a query like "1, halt, 2";
17-
// the first value is 1, and the second value is a HaltError with nil value.
18-
// You might think the iterator should not emit an error this case, but it
19-
// should so that we can recognize the halt error to stop the outer loop
20-
// of iterating input values; echo 1 2 3 | gojq "., halt".
21-
type HaltError interface {
22-
ValueError
23-
isHaltError()
24-
}
25-
2614
type expectedObjectError struct {
2715
v any
2816
}
@@ -192,22 +180,27 @@ func (err *exitCodeError) ExitCode() int {
192180
return err.code
193181
}
194182

195-
type haltError exitCodeError
183+
// HaltError is an error emitted by halt and halt_error functions.
184+
// It implements [ValueError], and if the value is nil, discard the error
185+
// and stop the iteration. Consider a query like "1, halt, 2";
186+
// the first value is 1, and the second value is a HaltError with nil value.
187+
// You might think the iterator should not emit an error this case, but it
188+
// should so that we can recognize the halt error to stop the outer loop
189+
// of iterating input values; echo 1 2 3 | gojq "., halt".
190+
type HaltError exitCodeError
196191

197-
func (err *haltError) Error() string {
192+
func (err *HaltError) Error() string {
198193
return "halt " + (*exitCodeError)(err).Error()
199194
}
200195

201-
func (err *haltError) Value() any {
196+
func (err *HaltError) Value() any {
202197
return (*exitCodeError)(err).Value()
203198
}
204199

205-
func (err *haltError) ExitCode() int {
200+
func (err *HaltError) ExitCode() int {
206201
return (*exitCodeError)(err).ExitCode()
207202
}
208203

209-
func (err *haltError) isHaltError() {}
210-
211204
type flattenDepthError struct {
212205
v float64
213206
}

execute.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ loop:
9292
case *tryEndError:
9393
err = e.err
9494
break loop
95-
case *breakError, *haltError:
95+
case *breakError, *HaltError:
9696
break loop
9797
case ValueError:
9898
env.pop()

func.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,7 +2099,7 @@ func funcError(v any, args []any) any {
20992099
}
21002100

21012101
func funcHalt(any) any {
2102-
return &haltError{nil, 0}
2102+
return &HaltError{nil, 0}
21032103
}
21042104

21052105
func funcHaltError(v any, args []any) any {
@@ -2110,7 +2110,7 @@ func funcHaltError(v any, args []any) any {
21102110
return &func0TypeError{"halt_error", args[0]}
21112111
}
21122112
}
2113-
return &haltError{v, code}
2113+
return &HaltError{v, code}
21142114
}
21152115

21162116
func toInt(x any) (int, bool) {

query_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func TestQueryRun_Halt(t *testing.T) {
105105
break
106106
}
107107
if err, ok := v.(error); ok {
108-
if _, ok := err.(gojq.HaltError); ok {
108+
if _, ok := err.(*gojq.HaltError); ok {
109109
break
110110
}
111111
t.Errorf("should emit a halt error but got: %v", err)
@@ -127,7 +127,7 @@ func TestQueryRun_HaltError(t *testing.T) {
127127
break
128128
}
129129
if err, ok := v.(error); ok {
130-
if _, ok := err.(gojq.HaltError); ok {
130+
if _, ok := err.(*gojq.HaltError); ok {
131131
if expected := "halt error: foo"; err.Error() != expected {
132132
t.Errorf("expected: %v, got: %v", expected, err)
133133
}

0 commit comments

Comments
 (0)