※編集2017/7/20 handler内で、Responseがcommit済みなら処理しないようにif文追加
各種バージョン
Go 1.8.4
echo 3.2.1
echoのデフォルト
echoは、エラー発生時にデフォルトではシンプルなjsonが返ってくる。
webサービスを実装していてエラーページを返したい場合は、独自に実装が必要。
独自ErrorHandlerを準備する
import (
"fmt"
"github.com/labstack/echo"
"net/http"
"runtime"
"strconv"
)
func CustomHTTPErrorHandler(err error, c echo.Context) {
if !c.Response().Committed {
code := http.StatusInternalServerError
if he, ok := err.(*echo.HTTPError); ok {
code = he.Code
}
stackTrace := ""
for depth := 0; ; depth++ {
pc, src, line, ok := runtime.Caller(depth)
if !ok || depth > 30 { //30行までしかStacktrace表示しない
break
}
stackTrace += fmt.Sprintf(" -> %d: %s: %s(%d)\n", depth, runtime.FuncForPC(pc).Name(), src, line)
}
errorData := struct {
Message string
StackTrace string
}{
Message: err.Error(),
StackTrace: stackTrace,
}
//StackTrace情報と、errorメッセージをテンプレートに送る。
//なお、テンプレートのhtmlファイル名は、<httpステータスコード>.htmlとする。例:500.html
if err = c.Render(http.StatusOK, strconv.Itoa(code), errorData); err != nil {
c.Logger().Error(err)
}
}
}
エラーに関するHTTPステータスコードのhtmlファイルをテンプレートとして用意する
- 500.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Error</title>
</head>
<body>
<pre>message:{{.Message}}</pre>
<pre>stacktrace:{{.StackTrace}}</pre>
</body>
</html>
server.goでhandlerをセット。
※テンプレート読み込み部分は省略
e.HTTPErrorHandler = CustomHTTPErrorHandler
これで、エラー発生時にhtmlエラーページが返せました。