errors

package
v1.26.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 21, 2026 License: MIT Imports: 0 Imported by: 0

Documentation

Overview

errorsパッケージは、エラーを操作するための関数を実装しています。

[New]関数は、テキストメッセージのみが含まれるエラーを作成します。

エラーeの型にメソッドが1つある場合、eは別のエラーをラップします。

Unwrap() error
Unwrap() []error

もしe.Unwrap()がnilでないエラーwまたはwを含むスライスを返した場合、 eはwをラップしていると言います。e.Unwrap()がnilを返した場合、 eは他のエラーをラップしていないことを示します。Unwrapメソッドが、 nilエラー値を含む[]errorを返すことは無効です。

ラップされたエラーを作成する簡単な方法は、 fmt.Errorf を呼び出し、 エラー引数に%w動詞を適用することです。

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

エラーの連続的なアンラップにより、ツリーが作成されます。 Is および As 関数は、エラーのツリーを調べるために、 最初にエラー自体を調べ、次にその子のツリーを順番に調べます (前順、深さ優先のトラバース)。

ラップの哲学とラップするタイミングについてのより深い議論については、 https://go.dev/blog/go1.13-errors を参照してください。

Is は、第1引数のツリーを調べて、第2引数と一致するエラーを探します。 一致するものが見つかったかどうかを報告します。単純な等価性チェックよりも 優先して使用すべきです:

if errors.Is(err, fs.ErrExist)

これは、次のようなエラーの比較よりも好ましいです。

if err == fs.ErrExist

なぜなら、前者はエラーが io/fs.ErrExist をラップしている場合に成功するからです。

As は、第1引数のエラーツリーを調べ、第2引数に割り当て可能なエラーを探します。 第2引数はポインタである必要があります。成功した場合、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)
}

なぜなら、前者はエラーが[*io/fs.PathError]をラップしている場合に成功するからです。

Example
if err := oops(); err != nil {
	fmt.Println(err)
}
Output:
1989-03-15 22:30:00 +0000 UTC: the file system has gone away

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrUnsupported = New("unsupported operation")

ErrUnsupportedは、サポートされていないため、要求された操作を実行できないことを示します。 たとえば、ハードリンクをサポートしていないファイルシステムを使用して os.Link を呼び出す場合。

関数やメソッドは、このエラーを返すべきではありません。 代わりに、適切な文脈を含むエラーを返すべきです。

errors.Is(err, errors.ErrUnsupported)

ErrUnsupportedを直接ラップするか、 Is メソッドを実装することによって、 サポートされていないことを示すエラーを返すことができます。

関数やメソッドは、このエラーをラップして返す場合があることを文書化する必要があります。

Functions

func As added in v1.13.0

func As(err error, target any) bool

Asは、errのツリー内で最初にtargetに一致するエラーを検索し、 一致するエラーが見つかった場合、targetをそのエラー値に設定してtrueを返します。 それ以外の場合、falseを返します。

このツリーは、err自体と、その後に繰り返しUnwrap() errorまたはUnwrap() []errorメソッドを 呼び出すことで得られるエラーで構成されています。errが複数のエラーをラップしている場合、 Asはerrとその子の深さ優先探索を順に調べます。

エラーがターゲットに一致する場合、エラーの具体的な値がtargetが指す値に代入可能であるか、 またはエラーがAs(any) boolというメソッドを持ち、As(target)がtrueを返す場合です。 後者の場合、Asメソッドはtargetを設定する責任があります。

エラータイプは、異なるエラータイプであるかのように扱うことができるように、Asメソッドを提供する場合があります。

Asは、targetがエラーを実装する型または任意のインターフェース型の、 非nilポインタでない場合にパニックを引き起こします。

Example
package main

import (
	"github.com/shogo82148/std/errors"
	"github.com/shogo82148/std/fmt"
	"github.com/shogo82148/std/io/fs"
	"github.com/shogo82148/std/os"
)

func main() {
	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)
		}
	}

}
Output:
Failed at path: non-existing
Example (Custom_match)

カスタムエラーは "As(any) bool" メソッドを実装することで他のエラー型とマッチングでき、 errors.As のデフォルトマッチングを上書きします。

var err error = MyAsError{"an error"}
fmt.Println("Error:", err)
fmt.Printf("TypeOf err: %T\n", err)

var pathError *fs.PathError
ok := errors.As(err, &pathError)
fmt.Println("Error as fs.PathError:", ok)
fmt.Println("fs.PathError:", pathError)
Output:
Error: an error
TypeOf err: errors_test.MyAsError
Error as fs.PathError: true
fs.PathError: custom /: an error

func Is added in v1.13.0

func Is(err, target error) bool

Isは、errのツリー内にあるいずれかのエラーがtargetと一致するかどうかを報告します。 targetは比較可能でなければなりません。

このツリーは、err自体と、その後に繰り返しUnwrap() errorまたはUnwrap() []errorメソッドを 呼び出すことで得られるエラーで構成されています。errが複数のエラーをラップしている場合、 Isはerrとその子の深さ優先探索を順に調べます。

ターゲットに一致するエラーは、そのターゲットに等しい場合、または 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とターゲットを浅く比較し、Unwrap を呼び出さないようにする必要があります。

Example
package main

import (
	"github.com/shogo82148/std/errors"
	"github.com/shogo82148/std/fmt"
	"github.com/shogo82148/std/io/fs"
	"github.com/shogo82148/std/os"
)

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

}
Output:
file does not exist
Example (Custom_match)

Custom errors can implement a method "Is(error) bool" to match other error values, overriding the default matching of errors.Is.

var err error = MyIsError{"an error"}
fmt.Println("Error equals fs.ErrPermission:", err == fs.ErrPermission)
fmt.Println("Error is fs.ErrPermission:", errors.Is(err, fs.ErrPermission))
Output:
Error equals fs.ErrPermission: false
Error is fs.ErrPermission: true

func Join added in v1.20.0

func Join(errs ...error) error

Joinは、指定されたエラーをラップするエラーを返します。 nilエラー値は破棄されます。 errsのすべての値がnilの場合、Joinはnilを返します。 エラーは、errsの各要素のErrorメソッドを呼び出して得られた文字列を連結したもので、 各文字列の間に改行が挿入されたものとしてフォーマットされます。

Joinによって返されるnilでないエラーは、Unwrap() []errorメソッドを実装します。

Example
package main

import (
	"github.com/shogo82148/std/errors"
	"github.com/shogo82148/std/fmt"
)

func main() {
	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")
	}
	fmt.Println(err.(interface{ Unwrap() []error }).Unwrap())
}
Output:
err1
err2
err is err1
err is err2
[err1 err2]

func New

func New(text string) error

Newは、指定されたテキストをフォーマットするエラーを返します。 テキストが同じであっても、Newの各呼び出しは異なるエラー値を返します。

Example
package main

import (
	"github.com/shogo82148/std/errors"
	"github.com/shogo82148/std/fmt"
)

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

The fmt package's Errorf function lets us use the package's formatting features to create descriptive error messages.

package main

import (
	"github.com/shogo82148/std/fmt"
)

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

Each call to errors.New returns an unique instance of the error, even if the arguments are the same. To match against errors created by errors.New, declare a sentinel error and reuse it.

err1 := OopsNew()
err2 := OopsNew()
fmt.Println("Errors using distinct errors.New calls:")
fmt.Printf("Is(%q, %q) = %v\n", err1, err2, errors.Is(err1, err2))

err3 := OopsSentinel()
err4 := OopsSentinel()
fmt.Println()
fmt.Println("Errors using a sentinel error:")
fmt.Printf("Is(%q, %q) = %v\n", err3, err4, errors.Is(err3, err4))
Output:
Errors using distinct errors.New calls:
Is("an error", "an error") = false

Errors using a sentinel error:
Is("an error", "an error") = true

func Unwrap added in v1.13.0

func Unwrap(err error) error

Unwrapは、errの型にUnwrapメソッドが含まれている場合、 errのUnwrapメソッドを呼び出した結果を返します。 それ以外の場合、Unwrapはnilを返します。

Unwrapは、"Unwrap() error"形式のメソッドのみを呼び出します。 特に、Unwrapは Join によって返されたエラーをアンラップしません。

Example
package main

import (
	"github.com/shogo82148/std/errors"
	"github.com/shogo82148/std/fmt"
)

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

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL