Skip to content

Commit

Permalink
map: include errnos with errors
Browse files Browse the repository at this point in the history
We replace some errnos from map syscalls with more descriptive
sentinel errors. Include the original errno with the error so
that both

    errors.Is(err, ErrKeyNotExist)
    errors.Is(err, unix.ENOENT)

work. We'll use this for other errors in the future where we
want to introduce our own errors without breaking callers that
rely on the (coarser) errno semantics.
  • Loading branch information
lmb committed Jul 2, 2021
1 parent 12affbf commit ca49208
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
17 changes: 17 additions & 0 deletions internal/syscall.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,20 @@ type wrappedErrno struct {
func (we wrappedErrno) Unwrap() error {
return we.Errno
}

type syscallError struct {
error
errno syscall.Errno
}

func SyscallError(err error, errno syscall.Errno) error {
return &syscallError{err, errno}
}

func (se *syscallError) Is(target error) bool {
return target == se.error
}

func (se *syscallError) Unwrap() error {
return se.errno
}
21 changes: 21 additions & 0 deletions internal/syscall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,24 @@ func TestWrappedErrno(t *testing.T) {
t.Error("errors.Is(wrappedErrno, EAGAIN) returns true")
}
}

func TestSyscallError(t *testing.T) {
err := errors.New("foo")
foo := SyscallError(err, unix.EINVAL)

if !errors.Is(foo, unix.EINVAL) {
t.Error("SyscallError is not the wrapped errno")
}

if !errors.Is(foo, err) {
t.Error("SyscallError is not the wrapped error")
}

if errors.Is(unix.EINVAL, foo) {
t.Error("Errno is the SyscallError")
}

if errors.Is(err, foo) {
t.Error("Error is the SyscallError")
}
}
6 changes: 3 additions & 3 deletions syscalls.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,15 +361,15 @@ func wrapMapError(err error) error {
}

if errors.Is(err, unix.ENOENT) {
return ErrKeyNotExist
return internal.SyscallError(ErrKeyNotExist, unix.ENOENT)
}

if errors.Is(err, unix.EEXIST) {
return ErrKeyExist
return internal.SyscallError(ErrKeyExist, unix.EEXIST)
}

if errors.Is(err, unix.ENOTSUPP) {
return ErrNotSupported
return internal.SyscallError(ErrNotSupported, unix.ENOTSUPP)
}

return err
Expand Down

0 comments on commit ca49208

Please sign in to comment.