【Go】Echo エラー処理を実装する

apiサーバーの実装でとりあえずのエラー処理中。とりあえず以下をハンドリングするような想定で。
・ビジネスエラー
・システムエラー
・404エラー
・その他サーバーエラー

ディレクトリ構成はこんな感じ

$ tree -L 3
.
└── app
    ├── controller
    │   └── traking.go
    ├── error
    │   ├── business.go
    │   └── system.go
    ├── handler
    │   └── handler.go
    ├── main.go
独自エラーの実装

Messageはユーザーに伝えるメッセージ。
LogMessageはログとかに残すメッセージ(後で実装する予定)

app/error/system.go

package error

import(
  "fmt"
)

type SystemError struct {
  Message string
  LogMessage string
}

func (err *SystemError) Error() string {
  return fmt.Sprintf("%s", err.Message)
}
エラーハンドリング

とりあえずJSONをかえすところまで実装。

app/handler/handler.go

package handler

import(
  AppErr "app/error"
  "net/http"
  "github.com/labstack/echo"
)

type ApiError struct {
  Status int `json:status`
  Message string `json:message`
}

func JSONErrorHandler(err error, c echo.Context) {
  switch e := err.(type) {
  case *AppErr.BusinessError:
    // Business Error                                                                                                                                                                                              
    c.JSON(
      http.StatusOK, ApiError{
        Status: 200,
        Message: e.Message,
      })
  case *AppErr.SystemError:
      // System Error                                                                                                                                                                                              
      c.JSON(http.StatusOK, ApiError{
        Status: 500,
        Message: e.Message,
      })
  default:
    if he, ok := err.(*echo.HTTPError); ok {
      if he.Code == 404 {
        // 404                                                                                                                                                                                                     
        c.JSON(he.Code, ApiError{
          Status: he.Code,
          Message: "Not Found",
        })
      } else {
        // その他サーバーエラー                                                                                                                                                                                    
        c.JSON(he.Code, ApiError{
          Status: he.Code,
          Message: "System Error",
        })
      }
    }
  }
}

main.go

package main

import (
  AppErr "app/error"
  "app/handler"
)

func main() {
  e := echo.New()

  e.GET("/users", func(c echo.Contet) error {
    return &AppErr.System{ Message: "システムエラーだよ" }
    // return echo.NewHTTPError(http.StatusInternalServerError, "Server Error")
    // return echo.NewHTTPError(http.StatusNotFound, "Not Found")
  })

  e.HTTPErrorHandler = handler.JSONErrorHandler

  e.Start(":8080")
}

とりあえずやりたいことはできた。色々実装したら全然足りなそうだけど一旦はこれで。以上です。