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

Iter function with no outputs in a path(...) throws errors #191

Closed
wader opened this issue Sep 29, 2022 · 4 comments
Closed

Iter function with no outputs in a path(...) throws errors #191

wader opened this issue Sep 29, 2022 · 4 comments

Comments

@wader
Copy link
Contributor

wader commented Sep 29, 2022

Version: 9bf7af3

I noticed while debugging a path expression query and because in fq debug is implemented by some io functions that print and return empty iterator. So debug is defined something like this: def debug: (["DEBUG", .] | tojson | _write), .

Reproduction:

package main

import (
	"log"
	"os"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse(os.Args[1])
	if err != nil {
		panic(err)
	}

	code, err := gojq.Compile(query,
		gojq.WithIterFunction("a", 0, 0, func(i1 interface{}, i2 []interface{}) gojq.Iter {
			log.Println("in a")
			return gojq.NewIter()
		}),
	)
	if err != nil {
		panic(err)
	}

	iter := code.Run(nil)

	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			log.Printf("err: %#+v\n", err)
			break
		}
		log.Printf("v: %#+v\n", v)
	}
}
# this seems to come from the Iter case in execute.go
$ go run test.go 'try path(a) catch .'
2022/09/29 12:47:56 in a
2022/09/29 12:47:56 v: "invalid path on iterating against: gojq.Iter"

# gojq.emptyIter{} is probably because of the special 0 values case in gojq.NewIter()
$ go run test.go 'path(a)'
2022/09/29 12:47:59 in a
2022/09/29 12:47:59 err: &gojq.invalidPathIterError{v:gojq.emptyIter{}}

I would have expect it to work like empty. That is only do invalid path check if the Iter outputted some value.

$ go run test.go 'path(empty)'
<no output at all>
@itchyny
Copy link
Owner

itchyny commented Sep 29, 2022

Maybe I rejected against Iters just in case without deep considerations. Do we need to make gojq.NewIter(errors.New("hello")) works as error("hello") so that path(error(f)) should emit a hello error? Or what happens for gojq.WithIterFunction("f", 0, 0, func(v interface{}, _ []interface{}) gojq.Iter { return gojq.NewIter(v) }) which would be expected to work like def f: .;. Checking against emitted non-error values would be enough.

@wader
Copy link
Contributor Author

wader commented Sep 29, 2022

Yes being able to output an error without causing invalid path error would be good i think. Being able to make it work like def f: .; i think would require to output a "suffix"-path for each value somehow i guess? feels like that could get complicated.

So would a sane behaviour for a WithIterFunction inside a path(...) be that it has to either emit no values at all or output an error that gets thrown and iteration stops? all other cases cause invalid path?

@itchyny
Copy link
Owner

itchyny commented Sep 29, 2022

Fixed the issue.

wader added a commit to wader/fq that referenced this issue Sep 29, 2022
Fixes: Iter function with no outputs in a path(...) throws errors
itchyny/gojq#191
@wader
Copy link
Contributor Author

wader commented Sep 29, 2022

Thanks!

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

No branches or pull requests

2 participants