Go version

go version go1.22.0 darwin/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/Users/mikeschinkel/Library/Caches/go-build'
GOENV='/Users/mikeschinkel/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/mikeschinkel/go/gopath/pkg/mod'
GONOPROXY='github.com/newclarity/*'
GONOSUMDB='github.com/newclarity/*'
GOOS='darwin'
GOPATH='/Users/mikeschinkel/go/gopath'
GOPRIVATE='github.com/newclarity/*'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/mikeschinkel/go/go1.22.0'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/mikeschinkel/go/go1.22.0/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.22.0'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/fg/1dfmwyrx3wxbhj5lbdqpt7bw0000gn/T/go-build1267079162=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

Call scanner.Scan() on a closed file handle:

fh, _ := os.Open(f.Filepath())
fh.Close() // This by accident, long story
scanner = bufio.NewScanner(fh)
for scanner.Scan() {
   print("Never printed")
} 
if err := scanner.Err(); err != nil {
   print("Never saw an error")
}

What did you see happen?

scanner.Err() did not set an error telling me the file was already closed.

What did you expect to see?

An error to be set after the call to s.r.Read() within scanner.Scan when s.r.Read() returns an err that the file is already closed.


I would love to submit a PR for this with just a little guidance.

Should I just set the error to fs.ErrClosed or do I create a new error bufio.ErrFileClosed here and set that instead when fs.ErrClosed occurs?

Also, if I need to return a new error then for performance reasons should I use err==fs.ErrClosed or do I need to use errors.Is(err,fs.ErrClosed) for robustness?

If you want me to submit a PR for this and you give me this guidance I will be happy to follow the contributors guidelines and submit a PR. I have already signed the contributor license agreement.

Comment From: gabyhelp

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

Comment From: ianlancetaylor

I can't recreate the problem. When I run this program:

package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
)

func main() {
    f, err := os.Open("/")
    if err != nil {
        log.Fatal(err)
    }
    f.Close()
    s := bufio.NewScanner(f)
    for s.Scan() {
        log.Fatal("impossible")
    }
    fmt.Printf("error: %v\n", s.Err())
}

I get

error: read /: file already closed

Comment From: mikeschinkel

@ianlancetaylor — My bad. I was running into some other problems evidently and when I did not see the error being immediately checked after the read I made an incorrect assumption. But debugging through it I now see that the err is checked later.

Sorry for the trouble.

Comment From: ianlancetaylor

Thanks for following up.