Spec-Zone.ru › Go

Пакет errors

  • import "errors"
  • Обзор
  • Индекс
  • Примеры

Обзор

Пакет errors реализует функции для работы с ошибками.

Функция New создаёт ошибки, содержимым которых является только текстовое сообщение.

Ошибка e оборачивает другую ошибку, если тип e имеет один из методов

Unwrap() error
Unwrap() []error

Если e.Unwrap() возвращает не nil ошибку w или срез, содержащий w, то мы говорим, что e оборачивает w. Возвращение nil ошибки из e.Unwrap() указывает, что e не оборачивает никакую ошибку. Недопустимо, чтобы метод Unwrap возвращал []error, содержащий значение nil.

Простой способ создать оборачивающую ошибку — вызвать fmt.Errorf и применить к аргументу ошибки %w:

wrapsErr := fmt.Errorf("... %w ...", ..., err, ...)

Последовательное распаковку ошибки создаёт дерево. Функции Is и As проверяют дерево ошибки, сначала проверяя саму ошибку, а затем дерево каждого из её дочерних элементов по очереди (обход в глубину по принципу «префикс»).

Функция Is проверяет дерево своего первого аргумента, ища ошибку, соответствующую второму. Она сообщает, найдена ли такая ошибка. Её следует использовать вместо простых проверок на равенство:

if errors.Is(err, fs.ErrExist)

предпочтительнее

if err == fs.ErrExist

потому что в первом случае будет успех, если err оборачивает io/fs.ErrExist.

Функция As проверяет дерево своего первого аргумента, ища ошибку, которую можно присвоить своему второму аргументу, который должен быть указателем. Если поиск успешен, то выполняется присваивание и возвращается true. В противном случае возвращается false. Форма

var perr *fs.PathError
if errors.As(err, &perr) {
	fmt.Println(perr.Path)
}

предпочтительнее

if perr, ok := err.(*fs.PathError); ok {
	fmt.Println(perr.Path)
}

потому что в первом случае будет успех, если err оборачивает *io/fs.PathError.

Пример

Код:

if err := oops(); err != nil {
    fmt.Println(err)
}

Вывод:

1989-03-15 22:30:00 +0000 UTC: the file system has gone away

Индекс

  • Переменные
  • func As(err error, target any) bool
  • func Is(err, target error) bool
  • func Join(errs ...error) error
  • func New(text string) error
  • func Unwrap(err error) error

Примеры

Пакет
As
Is
Join
New
New (Errorf)
Unwrap

Файлы пакета

errors.go join.go wrap.go

Переменные

ErrUnsupported указывает, что запрошенная операция не может быть выполнена, так как она не поддерживается. Например, вызов os.Link при использовании файловой системы, которая не поддерживает жёсткие ссылки.

Функции и методы не должны возвращать эту ошибку, а вместо этого должны возвращать ошибку, включающую соответствующий контекст, который удовлетворяет

errors.Is(err, errors.ErrUnsupported)

либо непосредственно оборачивая ErrUnsupported, либо реализуя метод Is.

Функции и методы должны документировать случаи, в которых будет возвращена ошибка, оборачивающая эту ошибку.

var ErrUnsupported = New("unsupported operation")

func As 1.13

func As(err error, target any) bool

As находит первую ошибку в дереве err, которая соответствует target, и, если такая ошибка найдена, устанавливает target в значение этой ошибки и возвращает true. В противном случае возвращает false.

Дерево состоит из самой err и ошибок, полученных путём многократного вызова метода Unwrap() error или Unwrap() []error. Когда err оборачивает несколько ошибок, As проверяет err и затем выполняет обход в глубину по своим дочерним элементам.

Ошибка соответствует target, если её конкретное значение присваиваемо значению, на которое указывает target, или если ошибка имеет метод As(any) bool, такой что As(target) возвращает true. В последнем случае метод As отвечает за установку target.

Тип ошибки может предоставить метод As, чтобы его можно было рассматривать как другой тип ошибки.

As вызывает ошибку, если target не является непустым указателем либо на тип, реализующий error, либо на любой тип интерфейса.

Пример

Код:

if _, err := os.Open("non-existing"); err != nil {
    var pathError *fs.PathError
    if errors.As(err, &pathError) {
        fmt.Println("Failed at path:", pathError.Path)
    } else {
        fmt.Println(err)
    }
}

Вывод:

Failed at path: non-existing

func Is 1.13

func Is(err, target error) bool

Is сообщает, соответствует ли какая-либо ошибка в дереве err target.

Дерево состоит из самой err и ошибок, полученных путём многократного вызова метода Unwrap() error или Unwrap() []error. Когда err оборачивает несколько ошибок, Is проверяет err и затем выполняет обход в глубину по своим дочерним элементам.

Ошибка считается соответствующей target, если она равна этому target или если она реализует метод Is(error) bool, такой что Is(target) возвращает true.

Тип ошибки может предоставить метод Is, чтобы его можно было рассматривать как эквивалентный существующей ошибке. Например, если MyError определяет

func (m MyError) Is(target error) bool { return target == fs.ErrExist }

тогда Is(MyError{}, fs.ErrExist) возвращает true. См. syscall.Errno.Is в стандартной библиотеке для примера. Метод Is должен выполнять только поверхностное сравнение err и target, а не вызывать Unwrap ни для одной из них.

Пример

Код:

if _, err := os.Open("non-existing"); err != nil {
    if errors.Is(err, fs.ErrNotExist) {
        fmt.Println("file does not exist")
    } else {
        fmt.Println(err)
    }
}

Вывод:

file does not exist

func Join 1.20

func Join(errs ...error) error

Join возвращает ошибку, которая оборачивает заданные ошибки. Любые значения nil ошибки игнорируются. Join возвращает nil, если все значения в errs являются nil. Ошибка форматируется как конкатенация строк, полученных путём вызова метода Error каждого элемента errs, с новой строкой между каждой строкой.

Непустая ошибка, возвращённая Join, реализует метод Unwrap() []error.

Пример

Код:

err1 := errors.New("err1")
err2 := errors.New("err2")
err := errors.Join(err1, err2)
fmt.Println(err)
if errors.Is(err, err1) {
    fmt.Println("err is err1")
}
if errors.Is(err, err2) {
    fmt.Println("err is err2")
}

Вывод:

err1
err2
err is err1
err is err2

func New

func New(text string) error

New возвращает ошибку, которая форматируется как заданный текст. Каждый вызов New возвращает отличное от других значение ошибки, даже если текст идентичен.

Пример

Код:

err := errors.New("emit macho dwarf: elf header corrupted")
if err != nil {
    fmt.Print(err)
}

Вывод:

emit macho dwarf: elf header corrupted

Пример (Errorf)

Функция Errorf из пакета fmt позволяет нам использовать возможности форматирования пакета для создания описательных сообщений об ошибках.

Код:

const name, id = "bimmler", 17
err := fmt.Errorf("user %q (id %d) not found", name, id)
if err != nil {
    fmt.Print(err)
}

Вывод:

user "bimmler" (id 17) not found

func Unwrap 1.13

func Unwrap(err error) error

Unwrap возвращает результат вызова метода Unwrap на err, если тип err содержит метод Unwrap, возвращающий ошибку. В противном случае Unwrap возвращает nil.

Unwrap вызывает только метод вида «Unwrap() error». В частности, Unwrap не распаковывает ошибки, возвращаемые Join.

Пример

Код:

err1 := errors.New("error1")
err2 := fmt.Errorf("error2: [%w]", err1)
fmt.Println(err2)
fmt.Println(errors.Unwrap(err2))

Вывод:

error2: [error1]
error1

© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/errors/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API