mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
os: don't consult Is methods on non-syscall error types
CL #163058 moves interpretation of platform-specific errors to the syscall package. Package syscall errors implement an Is method which os.IsPermission etc. consult. This results in an unintended semantic change to the os package predicate functions: The following program now prints 'true' where it used to print 'false': package main import "os" type myError struct{ error } func (e myError) Is(target error) bool { return target == os.ErrPermission } func main() { println(os.IsPermission(myError{})) } Change the os package error predicate functions to only examine syscall errors, avoiding this semantic change. This CL does retain one minor semantic change: On Plan9, os.IsPermission used to return true for any error with text containing the string "permission denied". It now only returns true for a syscall.ErrorString containing that text. Change-Id: I6b512b1de6ced46c2f1cc8d264fa2495ae7bf9f5 Reviewed-on: https://go-review.googlesource.com/c/go/+/188817 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
55e23cb1fe
commit
d178c5888f
4 changed files with 32 additions and 1 deletions
|
|
@ -115,7 +115,8 @@ func underlyingErrorIs(err, target error) bool {
|
||||||
if err == target {
|
if err == target {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
e, ok := err.(interface{ Is(error) bool })
|
// To preserve prior behavior, only examine syscall errors.
|
||||||
|
e, ok := err.(syscallErrorType)
|
||||||
return ok && e.Is(target)
|
return ok && e.Is(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
11
src/os/error_errno.go
Normal file
11
src/os/error_errno.go
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !plan9
|
||||||
|
|
||||||
|
package os
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
type syscallErrorType = syscall.Errno
|
||||||
9
src/os/error_plan9.go
Normal file
9
src/os/error_plan9.go
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package os
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
type syscallErrorType = syscall.ErrorString
|
||||||
|
|
@ -175,3 +175,13 @@ func TestPathErrorUnwrap(t *testing.T) {
|
||||||
t.Error("errors.Is failed, wanted success")
|
t.Error("errors.Is failed, wanted success")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type myErrorIs struct{ error }
|
||||||
|
|
||||||
|
func (e myErrorIs) Is(target error) bool { return target == e.error }
|
||||||
|
|
||||||
|
func TestErrorIsMethods(t *testing.T) {
|
||||||
|
if os.IsPermission(myErrorIs{os.ErrPermission}) {
|
||||||
|
t.Error("os.IsPermission(err) = true when err.Is(os.ErrPermission), wanted false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue