/
error_handler.go
120 lines (98 loc) · 2.28 KB
/
error_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package goadmin
import (
"net/http"
"strings"
"github.com/CloudyKit/jet/v6"
"github.com/labstack/echo/v4"
)
func errorHandler(e error, ctx echo.Context) {
accept := ctx.Request().Header.Get(echo.HeaderAccept)
switch {
case strings.HasSuffix(ctx.Path(), "json"):
JSONError(e, ctx)
case strings.Contains(accept, "/json"):
JSONError(e, ctx)
case strings.Contains(accept, "text/html"):
HTMLError(e, ctx)
default:
HTTPError(e, ctx)
}
}
type viewData struct {
Code int
Title string
Error string
Details string
}
func (data viewData) JetVars() jet.VarMap {
vars := make(jet.VarMap)
vars.Set("code", data.Code)
vars.Set("error", data.Error)
vars.Set("title", data.Title)
vars.Set("details", data.Details)
vars.Set("scripts", JS)
vars.Set("styles", CSS)
return vars
}
func (viewData) JetData() map[string]interface{} {
return nil
}
func HTMLError(e error, ctx echo.Context) {
defer ctx.Logger().Errorf("html error: %s", e)
code := http.StatusInternalServerError
title, details := "", ""
if he, ok := e.(*echo.HTTPError); ok {
code = he.Code
if he.Internal != nil {
title = he.Internal.Error()
} else {
switch code {
case http.StatusBadRequest:
title = "Bad Request"
case http.StatusInternalServerError:
title = "Internal Server Error"
case http.StatusNotFound:
title = "Not Found"
}
}
}
data := &viewData{
Code: code,
Title: title,
Error: e.Error(),
Details: details,
}
err := ctx.Render(code, "errors/error.jet", data)
if err != nil {
ctx.Logger().Error(err)
}
}
func JSONError(e error, ctx echo.Context) {
defer ctx.Logger().Errorf("json error: %s", e)
code := http.StatusInternalServerError
if he, ok := e.(*echo.HTTPError); ok {
code = he.Code
}
resp := &Response{
Success: false,
Error: e.Error(),
}
if err := ctx.JSON(code, resp); err != nil {
ctx.Logger().Error(err)
}
}
type Response struct {
Success bool `json:"success"`
Error string `json:"error,omitempty"`
Data interface{} `json:"data,omitempty"`
}
func HTTPError(e error, ctx echo.Context) {
defer ctx.Logger().Errorf("http error: %s", e)
code := http.StatusInternalServerError
if he, ok := e.(*echo.HTTPError); ok {
code = he.Code
}
if err := ctx.NoContent(code); err != nil {
ctx.Logger().Error(err)
}
}