🦾

Go 独自Errorの作成 ~ 備忘録

2021/02/13に公開

書いた理由

  • API作成しているときにエラーって返すと思います。その際に独自でErrorを定義し返すというよくある内容をメモ化(作り込まず簡易)

独自エラーの定義

  • 独自のエラー型を定義するやり方
  • Goの組み込みのエラー型(error)は以下のような型です。
    (errorインタフェース)
type error interface {
    Error() string
}
  • func Error() string を実装した型は全てerrorインターフェースが実装されているものとみなす。(便利)

実際に書いてみた

package main

import (
	"fmt"
	"net/http"
	"encoding/json"
)

type ErrorMessage struct {
	Code    int
	Message string
}

// Errorメソッドさえ定義されていれば良い
func (e *ErrorMessage) Error() string {
	return e.Message
}

func errHandlerSample() error {
	return &ErrorMessage{
		Code: http.StatusBadRequest,
		Message: "sample error!!!",
	}
}

func main() {
	if err := errHandlerSample(); err != nil {
		switch err := err.(type) {
		case *ErrorMessage:
  		  // ErrorMessageの処理
  		  // switch文の頭で再定義したerr変数は*ErrorMessage型なので、
  		  // ErrorMessage型の各フィールドにアクセスできる。
  		  stJson := ErrorMessage{Code: err.Code, Message: err.Message}
  		  out, _ := json.Marshal(stJson)
  		  
https://twitter.com/MarcyWorkOut


https://twitter.com/MarcyWorkOut

fmt.Println(string(out))
		default:
			fmt.Println("Hello, playground")
		}
	}
}

結果: {"Code":400,"Message":"sample error!!!"}
  • 型キャストしSwitchで判定して出力しています。
  • 他にも判別する内容があればStructで定義しSwitchの判定に入れてください。
  • jsonで出力する部分は別途関数化して返す内容にしてもいいと思います。
func ResponseJSON(w http.ResponseWriter, obj interface{}, httpStatus int) error {
	b, err := json.Marshal(obj)
	if err != nil {
		return err.Error()
	}
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Content-Length", fmt.Sprintf("%d", len(b)))
	w.WriteHeader(httpStatus)
	w.Write(b)
	return nil
}

終わりに

  • 「func Error() string を実装した型は全てerrorインターフェースが実装されているものとみなす」 ので気軽に独自にError作成を作成できより状態に合わせて作成できます。

参考記事

Go言語のエラーハンドリングについて
WebAPIでエラーをどう表現すべき?15のサービスを調査してみた

Discussion