diff options
Diffstat (limited to 'echo/error_handler.go')
-rw-r--r-- | echo/error_handler.go | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/echo/error_handler.go b/echo/error_handler.go index 6874eff..a0bdd60 100644 --- a/echo/error_handler.go +++ b/echo/error_handler.go | |||
@@ -10,17 +10,22 @@ import ( | |||
10 | "github.com/labstack/echo/v4" | 10 | "github.com/labstack/echo/v4" |
11 | ) | 11 | ) |
12 | 12 | ||
13 | // TODO: This should have some kind of HTML formatting of panics in debug mode | ||
14 | |||
15 | type ContentErrorHandler interface { | 13 | type ContentErrorHandler interface { |
16 | Handle(echo.Context, *echo.HTTPError) error | 14 | Handle(echo.Context, *echo.HTTPError) error |
17 | } | 15 | } |
18 | 16 | ||
17 | type ErrorHandler interface { | ||
18 | AddHandler(ContentErrorHandler, ...string) | ||
19 | HandleError(error, echo.Context) | ||
20 | } | ||
21 | |||
19 | type HTMLErrorHandler struct { | 22 | type HTMLErrorHandler struct { |
20 | r *TemplateRenderer | 23 | r *TemplateRenderer |
21 | fallback *template.Template | 24 | fallback *template.Template |
22 | } | 25 | } |
23 | 26 | ||
27 | var _ ContentErrorHandler = (*HTMLErrorHandler)(nil) | ||
28 | |||
24 | func NewHTMLErrorHandler(r *TemplateRenderer) *HTMLErrorHandler { | 29 | func NewHTMLErrorHandler(r *TemplateRenderer) *HTMLErrorHandler { |
25 | t, err := template.New("").Parse("<html><body><h1>Error</h1><pre>{{ .Message }}</pre></body></html>\n") | 30 | t, err := template.New("").Parse("<html><body><h1>Error</h1><pre>{{ .Message }}</pre></body></html>\n") |
26 | if err != nil { | 31 | if err != nil { |
@@ -58,12 +63,16 @@ func (h *HTMLErrorHandler) Handle(c echo.Context, e *echo.HTTPError) error { | |||
58 | 63 | ||
59 | type PlainTextErrorHandler struct{} | 64 | type PlainTextErrorHandler struct{} |
60 | 65 | ||
66 | var _ ContentErrorHandler = (*PlainTextErrorHandler)(nil) | ||
67 | |||
61 | func (h *PlainTextErrorHandler) Handle(c echo.Context, e *echo.HTTPError) error { | 68 | func (h *PlainTextErrorHandler) Handle(c echo.Context, e *echo.HTTPError) error { |
62 | return c.String(e.Code, fmt.Sprintf("%s", e.Message)) | 69 | return c.String(e.Code, fmt.Sprintf("%s", e.Message)) |
63 | } | 70 | } |
64 | 71 | ||
65 | type JSONErrorHandler struct{} | 72 | type JSONErrorHandler struct{} |
66 | 73 | ||
74 | var _ ContentErrorHandler = (*JSONErrorHandler)(nil) | ||
75 | |||
67 | func (h *JSONErrorHandler) Handle(c echo.Context, e *echo.HTTPError) error { | 76 | func (h *JSONErrorHandler) Handle(c echo.Context, e *echo.HTTPError) error { |
68 | code := e.Code | 77 | code := e.Code |
69 | message := e.Message | 78 | message := e.Message |
@@ -80,28 +89,32 @@ func (h *JSONErrorHandler) Handle(c echo.Context, e *echo.HTTPError) error { | |||
80 | 89 | ||
81 | type failsafeHandler struct{} | 90 | type failsafeHandler struct{} |
82 | 91 | ||
92 | var _ ContentErrorHandler = (*failsafeHandler)(nil) | ||
93 | |||
83 | func (h *failsafeHandler) Handle(c echo.Context, e *echo.HTTPError) error { | 94 | func (h *failsafeHandler) Handle(c echo.Context, e *echo.HTTPError) error { |
84 | c.Echo().Logger.Error("Error while processing error page: %s", e) | 95 | c.Echo().Logger.Error("Error while processing error page: %s", e) |
85 | c.JSON(http.StatusInternalServerError, e) | 96 | c.JSON(http.StatusInternalServerError, e) |
86 | return nil | 97 | return nil |
87 | } | 98 | } |
88 | 99 | ||
89 | type ErrorHandler struct { | 100 | type EchoErrorHandler struct { |
90 | types []contenttype.MediaType | 101 | types []contenttype.MediaType |
91 | typeMap map[string]ContentErrorHandler | 102 | typeMap map[string]ContentErrorHandler |
92 | failsafeHandler ContentErrorHandler | 103 | failsafeHandler ContentErrorHandler |
93 | } | 104 | } |
94 | 105 | ||
95 | func NewErrorHandler() *ErrorHandler { | 106 | var _ ErrorHandler = (*EchoErrorHandler)(nil) |
96 | return &ErrorHandler{ | 107 | |
108 | func NewEchoErrorHandler() *EchoErrorHandler { | ||
109 | return &EchoErrorHandler{ | ||
97 | types: []contenttype.MediaType{}, | 110 | types: []contenttype.MediaType{}, |
98 | typeMap: map[string]ContentErrorHandler{}, | 111 | typeMap: map[string]ContentErrorHandler{}, |
99 | failsafeHandler: &failsafeHandler{}, | 112 | failsafeHandler: &failsafeHandler{}, |
100 | } | 113 | } |
101 | } | 114 | } |
102 | 115 | ||
103 | func NewDefaultErrorHandler(tr *TemplateRenderer) *ErrorHandler { | 116 | func NewDefaultErrorHandler(tr *TemplateRenderer) *EchoErrorHandler { |
104 | h := NewErrorHandler() | 117 | h := NewEchoErrorHandler() |
105 | 118 | ||
106 | // The order of these is important, especially when negotiating */* | 119 | // The order of these is important, especially when negotiating */* |
107 | h.AddHandler(&JSONErrorHandler{}, "text/json", "application/json") | 120 | h.AddHandler(&JSONErrorHandler{}, "text/json", "application/json") |
@@ -111,8 +124,8 @@ func NewDefaultErrorHandler(tr *TemplateRenderer) *ErrorHandler { | |||
111 | return h | 124 | return h |
112 | } | 125 | } |
113 | 126 | ||
114 | func NewNoHTMLErrorHandler() *ErrorHandler { | 127 | func NewNoHTMLErrorHandler() *EchoErrorHandler { |
115 | h := NewErrorHandler() | 128 | h := NewEchoErrorHandler() |
116 | 129 | ||
117 | // The order of these is important, especially when negotiating */* | 130 | // The order of these is important, especially when negotiating */* |
118 | h.AddHandler(&JSONErrorHandler{}, "text/json", "application/json") | 131 | h.AddHandler(&JSONErrorHandler{}, "text/json", "application/json") |
@@ -121,14 +134,14 @@ func NewNoHTMLErrorHandler() *ErrorHandler { | |||
121 | return h | 134 | return h |
122 | } | 135 | } |
123 | 136 | ||
124 | func (h *ErrorHandler) AddHandler(eh ContentErrorHandler, contentTypes ...string) { | 137 | func (h *EchoErrorHandler) AddHandler(eh ContentErrorHandler, contentTypes ...string) { |
125 | for _, ct := range contentTypes { | 138 | for _, ct := range contentTypes { |
126 | h.types = append(h.types, contenttype.NewMediaType(ct)) | 139 | h.types = append(h.types, contenttype.NewMediaType(ct)) |
127 | h.typeMap[ct] = eh | 140 | h.typeMap[ct] = eh |
128 | } | 141 | } |
129 | } | 142 | } |
130 | 143 | ||
131 | func (h *ErrorHandler) castToHttpError(e error) *echo.HTTPError { | 144 | func (h *EchoErrorHandler) castToHttpError(e error) *echo.HTTPError { |
132 | he, ok := e.(*echo.HTTPError) | 145 | he, ok := e.(*echo.HTTPError) |
133 | if ok { | 146 | if ok { |
134 | if he.Internal != nil { | 147 | if he.Internal != nil { |
@@ -145,7 +158,7 @@ func (h *ErrorHandler) castToHttpError(e error) *echo.HTTPError { | |||
145 | } | 158 | } |
146 | } | 159 | } |
147 | 160 | ||
148 | func (h *ErrorHandler) negotiateContentType(r *http.Request) (ContentErrorHandler, error) { | 161 | func (h *EchoErrorHandler) negotiateContentType(r *http.Request) (ContentErrorHandler, error) { |
149 | var err error | 162 | var err error |
150 | 163 | ||
151 | ct, _, err := contenttype.GetAcceptableMediaType(r, h.types) | 164 | ct, _, err := contenttype.GetAcceptableMediaType(r, h.types) |
@@ -163,7 +176,7 @@ func (h *ErrorHandler) negotiateContentType(r *http.Request) (ContentErrorHandle | |||
163 | return handle, err | 176 | return handle, err |
164 | } | 177 | } |
165 | 178 | ||
166 | func (h *ErrorHandler) HandleError(err error, c echo.Context) { | 179 | func (h *EchoErrorHandler) HandleError(err error, c echo.Context) { |
167 | defer func() { | 180 | defer func() { |
168 | if r := recover(); r != nil { | 181 | if r := recover(); r != nil { |
169 | if err, ok := r.(error); !ok { | 182 | if err, ok := r.(error); !ok { |