#todo #2023/08 時点の知見をまとめたい
## 方針
[[errors.Is]]を使った同値判定のエラーハンドリング。
```go:main.go
package main
import (
"errors"
"fmt"
"github.com/tadashi-aikawa/go-error-handle/lib"
)
var (
UserError = errors.New("user error")
ServerError = errors.New("server error")
)
func errorHandling(x int) error {
if err := lib.DoSomething(x); err != nil {
switch {
case errors.Is(err, lib.ForbiddenError):
fallthrough
case errors.Is(err, lib.NotFoundError):
return UserError
case errors.Is(err, lib.InternalServerError):
return ServerError
}
}
return nil
}
func main() {
x := 404
if err := errorHandling(x); err != nil {
switch {
case errors.Is(err, UserError):
fmt.Printf("%d はユーザーエラーですね", x)
case errors.Is(err, ServerError):
fmt.Printf("%d はサーバーエラーですね", x)
}
}
fmt.Println("ok")
}
```
```go:lib/lib.go
package lib
import "errors"
var (
ForbiddenError = errors.New("forbidden")
NotFoundError = errors.New("not found error")
InternalServerError = errors.New("internal server error")
)
func DoSomething(x int) error {
switch x {
case 403:
return ForbiddenError
case 404:
return NotFoundError
case 500:
return InternalServerError
}
return nil
}
```
## メリット
- シンプルで直感的
## デメリット
- エラーメッセージが固定になってしまう
- スタックトレースは保存されない
- [[fmt.Errorf]]などでラップできない
以下の観点からクリティカルな問題ではないはず。
- 関数のインターフェースに渡された値は呼び出し元が知っている
- エラーで返却する必要はない
- 関数の実装による情報が必要ならログで出した方がいい
- 非公開実装を公開インターフェースのエラーメッセージに返すのは不適切
- 比較用に作成するエラーインスタンスで原因は分かるので問題ない
## MOC
- [[errors.Isとerrors.Asの違い]]