-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
testing/fstest: should use errors.Is instead of equality #47062
Comments
Btw, I can contribute the fix and possibly also the "merge" filesystem from the linked PR if desired. It merges any number and type of file systems into one overarching. |
|
Anyone know why io.EOF gets to be an exception to the advice in package errors about checking error identity? |
There is no reason to do this. Callers who want a stack trace when they receive an error can easily generate one themselves. Callers who don't want a stack trace should not be required to pay the costs of generating one. |
related #39155 |
Because the Also, checks for |
Is |
An I'm not certain if there are other interfaces in the standard library specified as returning a sentinel error. If there are, the rationale for As @seankhliao pointed out, there is more discussion of io.EOF and error wrapping in #39155. |
The linked discussion was informative, thank you. I parse
as entirely compatible with wrapping + errors.Is; if that's not the intent, it should probably be made more explicit? And it's not just the Read method of an io.Reader that's bound by this constraint, but apparently the ReadDir method of a fs.ReadDirFile, too. Others? |
OK, the discussion around EOF is interesting. Thanks for the explanation around that. My key takeaway is:
which in turn leaves me wonder why it is of type
I am not sure I understand that. When I get the error at a point where I want to print/debug/... it, I don't have the program counter of where the error originated from? How can I generate a stack trace at that point? Can you maybe please give me some pointers on how that would be done? I would like to see the same output as if the code would have panicked instead of returning an error. The only way I know of how of how that is achievable is using |
Wildly off-topic and singular comment about errors and stack traces
You're treating errors as if they were exceptions, deferring handling to some top level catch-all, I'm guessing. But errors aren't exceptions. Whatever first receives an error should handle it, and if handling means returning it further up the stack, it should always be annotated first. This way, provenance is clear. v, err := process(n)
if err != nil {
// return nil, err // no
return nil, fmt.Errorf("processing %d: %w", n, err) // yes
} |
errors.Is
Based on the conversation, it doesn't look like we're going to be able to make this change because of |
The specific case in The requirements for |
Change https://golang.org/cl/333149 mentions this issue: |
This requirement ensures that ReadDir implementations are as compatible as possible with "*os.File".ReadDir. The testing/fstest package already tests for equality to io.EOF. Updates #47062. Fixes #47086. Change-Id: I54f911a34e507a3db0abc4da55a19b7a50b35041 Reviewed-on: https://go-review.googlesource.com/c/go/+/333149 Reviewed-by: Michael Knyszek <mknyszek@google.com>
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What did you do?
I wrote an
fs.FS
implementation that wraps errors with a stacktrace. Therefore I don't returnio.EOF
buterrors.WithStack(io.EOF)
.fstest.TestFS()
fails at this line:go/src/testing/fstest/testfs.go
Line 186 in 912f075
because it uses
!=
instead oferrors.Is()
.I think all error checks in that test should instead use
errors.Is()
to check whether the right error is returned.What did you expect to see?
No test failure.
What did you see instead?
Test failure.
The text was updated successfully, but these errors were encountered: