错误类型

典型错误

// PathError 记录一个错误以及产生该错误的路径和操作。
type PathError struct {
	Op string    // "open"、"unlink" 等等。
	Path string  // 相关联的文件。
	Err error    // 由系统调用返回。
}

func (e *PathError) Error() string {
	return e.Op + " " + e.Path + ": " + e.Err.Error()
}

PathError 的 Error 会生成如下错误信息:

open /etc/passwx: no such file or directory

这种错误包含了出错的文件名、操作和触发的操作系统错误,即便在产生该错误的调用 和输出的错误信息相距甚远时,它也会非常有用,这比苍白的“不存在该文件或目录”更具说明性。

错误字符串应尽可能地指明它们的来源,例如产生该错误的包名前缀。例如在 image 包中,由于未知格式导致解码错误的字符串为“image: unknown format”。

若调用者关心错误的完整细节,可使用类型选择或者类型断言来查看特定错误,并抽取其细节。对于 PathErrors,它应该还包含检查内部的 Err 字段以进行可能的错误恢复。

for try := 0; try < 2; try++ {
	file, err = os.Create(filename)
	if err == nil {
		return
	}
	if e, ok := err.(*os.PathError); ok && e.Err == syscall.ENOSPC {
		deleteTempFiles()  // 恢复一些空间。
		continue
	}
	return
}

这里的第二条 if 是另一种类型断言。若它失败,ok 将为 false,而 e 则为 nil. 若它成功,ok 将为 true,这意味着该错误属于 *os.PathError 类型,而 e 能够检测关于该错误的更多信息。

预先定义好的错误,例如 os 包中预先定义好一系列错误,并且设置为导出变量,使用放可以通过导出变量来判读到底发生了何种类型的错误。

// Portable analogs of some common system call errors.
var (
	ErrInvalid    = errors.New("invalid argument") // methods on File will return this error when the receiver is nil
	ErrPermission = errors.New("permission denied")
	ErrExist      = errors.New("file already exists")
	ErrNotExist   = errors.New("file does not exist")
	ErrClosed     = errors.New("file already closed")
	ErrNoDeadline = poll.ErrNoDeadline
)
上一页