Conversation
Inside of `loadData()`, the `os.File` was being closed before its contents were read by `io.ReadAll()`. Defer the close operation until the end of the function.
| if err := f.Close(); err != nil { | ||
| return nil, err | ||
| } | ||
| defer f.Close() |
There was a problem hiding this comment.
I think we need to do something like
defer func() {
if err := f.Close(); err != nil {
// Somehow "handle" the error
}
}()to silence the linter
There was a problem hiding this comment.
One way that it can be handled to allow returning the error value to the caller, as well as other errors, is to use a helper function like this one with a named return value;
// Helper func: Pass in the function directly rather than calling the function
func joinErr(err *error, op func() error) {
*err = errors.Join(*err, op())
}
// Helper func: Read input from specified file or stdin
func loadData(p string) (_ []byte, err error) {
if p == "" {
return nil, fmt.Errorf("no path specified")
}
var rdr io.Reader
switch p {
case "-":
rdr = os.Stdin
case "+":
return []byte("{}"), nil
default:
f, err := os.Open(p)
if err != nil {
return nil, err
}
rdr = f
defer joinErr(&err, f.Close)
}
return io.ReadAll(rdr)
}VictoriaMetrics has a good blogpost on this as well as Uber having run into a similar issue and creating an "Invoker" interface.
There was a problem hiding this comment.
As a note, the function needs to use a named return value, which is a first for me (I've not really used named returns before), otherwise the deferred function updates the error value that is scoped to the function (and is already discarded)
Details here; https://gophers.slack.com/archives/C02A8LZKT/p1754303913406599
|
Oops, noticed this after putting up #472. But going to close this PR so we can get this fixed up. Nit, we shouldn't ignore the error (which is why the linter is complaining). |
File reading by cmd/jwt is failing. Inside of
loadData(), theos.Filewas being closed before its contents were read byio.ReadAll(). This leads errors like the following.The solution is to defer the close operation until the end of the function, which is the way the code had been written prior to PR #438.