Change os.Error convention:
echo back context of call in error if likely to be useful.
For example, if os.Open("/etc/passwd", os.O_RDONLY)
fails with syscall.EPERM, it returns as the os.Error
&PathError{
Op: "open",
Path: "/etc/passwd"
Error: os.EPERM
}
which formats as
open /etc/passwd: permission denied
Not converted:
datafmt
go/...
google/...
regexp
tabwriter
template
R=r
DELTA=1153 (561 added, 156 deleted, 436 changed)
OCL=30738
CL=30781
diff --git a/src/pkg/os/error.go b/src/pkg/os/error.go
index 718499b..10a7d04 100644
--- a/src/pkg/os/error.go
+++ b/src/pkg/os/error.go
@@ -30,15 +30,6 @@
return syscall.Errstr(int(e))
}
-// ErrnoToError converts errno to an Error (underneath, an Errno).
-// It returns nil for the "no error" errno.
-func ErrnoToError(errno int) Error {
- if errno == 0 {
- return nil
- }
- return Errno(errno)
-}
-
// Commonly known Unix errors.
var (
EPERM Error = Errno(syscall.EPERM);
@@ -81,3 +72,33 @@
ENAMETOOLONG Error = Errno(syscall.ENAMETOOLONG);
)
+// PathError records an error and the operation and file path that caused it.
+type PathError struct {
+ Op string;
+ Path string;
+ Error Error;
+}
+
+func (e *PathError) String() string {
+ return e.Op + " " + e.Path + ": " + e.Error.String();
+}
+
+// SyscallError records an error from a specific system call.
+type SyscallError struct {
+ Syscall string;
+ Errno Errno;
+}
+
+func (e *SyscallError) String() string {
+ return e.Syscall + ": " + e.Errno.String();
+}
+
+// NewSyscallError returns, as an os.Error, a new SyscallError
+// with the given system call name and error number.
+// As a convenience, if errno is 0, NewSyscallError returns nil.
+func NewSyscallError(syscall string, errno int) os.Error {
+ if errno == 0 {
+ return nil;
+ }
+ return &SyscallError{syscall, Errno(errno)}
+}