go error 源码

2022-07-15 浏览 (925)

golang error 代码

文件路径:/src/os/error.go

/ Copyright 2009 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 (
	"internal/oserror"
	"internal/poll"
	"io/fs"
)

/ Portable analogs of some common system call errors.
/
/ Errors returned from this package may be tested against these errors
/ with errors.Is.
var (
	/ ErrInvalid indicates an invalid argument.
	/ Methods on File will return this error when the receiver is nil.
	ErrInvalid = fs.ErrInvalid / "invalid argument"

	ErrPermission = fs.ErrPermission / "permission denied"
	ErrExist      = fs.ErrExist      / "file already exists"
	ErrNotExist   = fs.ErrNotExist   / "file does not exist"
	ErrClosed     = fs.ErrClosed     / "file already closed"

	ErrNoDeadline       = errNoDeadline()       / "file type does not support deadline"
	ErrDeadlineExceeded = errDeadlineExceeded() / "i/o timeout"
)

func errClosed() error     { return oserror.ErrClosed }
func errNoDeadline() error { return poll.ErrNoDeadline }

/ errDeadlineExceeded returns the value for os.ErrDeadlineExceeded.
/ This error comes from the internal/poll package, which is also
/ used by package net. Doing this this way ensures that the net
/ package will return os.ErrDeadlineExceeded for an exceeded deadline,
/ as documented by net.Conn.SetDeadline, without requiring any extra
/ work in the net package and without requiring the internal/poll
/ package to import os (which it can't, because that would be circular).
func errDeadlineExceeded() error { return poll.ErrDeadlineExceeded }

type timeout interface {
	Timeout() bool
}

/ PathError records an error and the operation and file path that caused it.
type PathError = fs.PathError

/ SyscallError records an error from a specific system call.
type SyscallError struct {
	Syscall string
	Err     error
}

func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() }

func (e *SyscallError) Unwrap() error { return e.Err }

/ Timeout reports whether this error represents a timeout.
func (e *SyscallError) Timeout() bool {
	t, ok := e.Err.(timeout)
	return ok && t.Timeout()
}

/ NewSyscallError returns, as an error, a new SyscallError
/ with the given system call name and error details.
/ As a convenience, if err is nil, NewSyscallError returns nil.
func NewSyscallError(syscall string, err error) error {
	if err == nil {
		return nil
	}
	return &SyscallError{syscall, err}
}

/ IsExist returns a boolean indicating whether the error is known to report
/ that a file or directory already exists. It is satisfied by ErrExist as
/ well as some syscall errors.
/
/ This function predates errors.Is. It only supports errors returned by
/ the os package. New code should use errors.Is(err, fs.ErrExist).
func IsExist(err error) bool {
	return underlyingErrorIs(err, ErrExist)
}

/ IsNotExist returns a boolean indicating whether the error is known to
/ report that a file or directory does not exist. It is satisfied by
/ ErrNotExist as well as some syscall errors.
/
/ This function predates errors.Is. It only supports errors returned by
/ the os package. New code should use errors.Is(err, fs.ErrNotExist).
func IsNotExist(err error) bool {
	return underlyingErrorIs(err, ErrNotExist)
}

/ IsPermission returns a boolean indicating whether the error is known to
/ report that permission is denied. It is satisfied by ErrPermission as well
/ as some syscall errors.
/
/ This function predates errors.Is. It only supports errors returned by
/ the os package. New code should use errors.Is(err, fs.ErrPermission).
func IsPermission(err error) bool {
	return underlyingErrorIs(err, ErrPermission)
}

/ IsTimeout returns a boolean indicating whether the error is known
/ to report that a timeout occurred.
/
/ This function predates errors.Is, and the notion of whether an
/ error indicates a timeout can be ambiguous. For example, the Unix
/ error EWOULDBLOCK sometimes indicates a timeout and sometimes does not.
/ New code should use errors.Is with a value appropriate to the call
/ returning the error, such as os.ErrDeadlineExceeded.
func IsTimeout(err error) bool {
	terr, ok := underlyingError(err).(timeout)
	return ok && terr.Timeout()
}

func underlyingErrorIs(err, target error) bool {
	/ Note that this function is not errors.Is:
	/ underlyingError only unwraps the specific error-wrapping types
	/ that it historically did, not all errors implementing Unwrap().
	err = underlyingError(err)
	if err == target {
		return true
	}
	/ To preserve prior behavior, only examine syscall errors.
	e, ok := err.(syscallErrorType)
	return ok && e.Is(target)
}

/ underlyingError returns the underlying error for known os error types.
func underlyingError(err error) error {
	switch err := err.(type) {
	case *PathError:
		return err.Err
	case *LinkError:
		return err.Err
	case *SyscallError:
		return err.Err
	}
	return err
}

相关信息

go 源码目录

相关文章

go dir 源码

go dir_darwin 源码

go dir_plan9 源码

go dir_unix 源码

go dir_windows 源码

go dirent_aix 源码

go dirent_dragonfly 源码

go dirent_freebsd 源码

go dirent_js 源码

go dirent_linux 源码

^