[Golang] エラー取り扱いまとめ

golang Golang

Go言語でのエラーの扱い方まとめ

個人メモです。逐次更新したいですが…

基本方針

例外が起きる可能性のある関数はすべてerrorを返すようにする

go言語は複数の値を返すことができるので、エラーが起きる可能性のある関数については常にエラーをリターン値の末尾に含めるようにします

スタックトレース

スタックトレースの取得はruntimeパッケージで行うことができます

package main

import (
    "fmt"
    "errors"
    "runtime"
)

// スタックトレースを取得する関数
func getStackTrace() string {
    buf := make([]byte, 1024)
    n := runtime.Stack(buf, false)
    return string(buf[:n])
}

// エラーを作成する関数
func doSomething() error {
    return fmt.Errorf("failed to do something: %s", getStackTrace())
}

func main() {
    err := doSomething()
    if err != nil {
        fmt.Println("Error:", err)
    }
}

エラーの判別

go1.13以降ではerror.Isなどを用いてエラーを判別できるようになっているようです。

import (
    "errors"
    "fmt"
)

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

func getItem(id int) (string, error) {
    if id == 0 {
        return "", fmt.Errorf("failed to get item: %w", ErrNotFound)
    }
    return "item", nil
}

func main() {
    _, err := getItem(0)
    if errors.Is(err, ErrNotFound) {
        fmt.Println("Item not found")
    }
}

エラーのraise方法

静的なエラーの場合

errors.Newで生成

import "errors"

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

func getItem(id int) (string, error) {
    if id == 0 {
        return "", ErrNotFound
    }
    return "item", nil
}

動的なエラーの場合

変数の内容などをエラーに含める場合はfmt.Errorfで生成

import "fmt"

func getItem(id int) (string, error) {
    if id == 0 {
        return "", fmt.Errorf("item with id %d not found", id)
    }
    return "item", nil
}

エラーチェーン

呼び出し元で呼び出し先のエラー情報を利用したい場合は、fmt.Errorfで同様にエラーをラップします

// 何らかのエラーを返す関数
func doSomething() error {
    return fmt.Errorf("failed to do something")
}

// さらに上位の関数でエラーをラップする
func process() error {
    err := doSomething()
    if err != nil {
        return fmt.Errorf("process failed: %w", err) // %w でエラーをラップ
    }
    return nil
}

参考文献

コメント

タイトルとURLをコピーしました