🐙

Golang エラー処理

2021/07/26に公開

エラー処理の方法

エラー処理の基本

student, err := getStudent(1000)
if err != nil {
    // errが nilの場合は、成功。
    // nil ではない場合は、失敗。
}

関数からエラーを返す

関数からエラーを返す場合、通常は最後の戻り値をエラーとする。

func getStudent(id int) (*Student, error) {
    student, err := getStudentFromExternal(id)
    if err != nil {
        return nil, err
    }
    return student, nil
}

エラーに情報を追加する

fmt.Errorf() 関数を使用し、エラーを返す。
次の例ではエラーの情報を追加した上で、元のエラーを返している。

func getStudent(id int) (*Student, error) {
    student, err := getStudentFromExternal(id)
    if err != nil {
        return nil, fmt.Errorf("Studentの取得時にエラーが発生: %v", err)
    }
    return student, nil
}

再利用可能なエラーの作成

var ErrNotFound = errors.New("Student not found!")

func getStudent(id int) (*Student, error) {
    if id != 1001 {
        return nil, ErrNotFound
    }

    student := Student{LastName: "Sato", FirstName: "Ryo"}
    return &student, nil
}

規則ではエラー変数のプレフィックスに「Err」を含めることになっている

エラーの種類判定

student, err := getStudent(1000)
if errors.Is(err, ErrNotFound) {
    fmt.Printf("NOT FOUND: %v\n", err)
} else {
    fmt.Print(student)
}

エラー処理に関する推奨事項

  • エラーが予想されなくても、エラーがないかどうかを常に確認する。 そのうえで、不要な情報がエンドユーザーに公開されないようにする。
  • エラーの発生元がわかるようにエラーメッセージにプレフィックスを含める。 例:パッケージや関数の名前を含める。
  • 可能な限り、再利用可能なエラー変数を作成する。
  • エラーを返すことと、パニックの違いを理解する。 他に対処方法がない場合は、パニックが発生する。 例:依存関係の準備ができていない場合、プログラムは動作しない。
  • 可能な限り多くの詳細情報でエラーをログに記録し、エンドユーザーが理解可能なエラーを出力する。
GitHubで編集を提案

Discussion