forked from neoxelox/kit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexception_handler.go
More file actions
68 lines (56 loc) · 1.52 KB
/
exception_handler.go
File metadata and controls
68 lines (56 loc) · 1.52 KB
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
package kit
import (
"net/http"
"github.com/labstack/echo/v4"
)
type ExceptionHandlerConfig struct {
Environment Environment
}
type ExceptionHandler struct {
config ExceptionHandlerConfig
observer Observer
}
func NewExceptionHandler(observer Observer, config ExceptionHandlerConfig) *ExceptionHandler {
return &ExceptionHandler{
observer: observer,
config: config,
}
}
func (self *ExceptionHandler) Handle(err error, ctx echo.Context) {
// If response was already committed it means another middleware or an actual view
// has already called the exception handler or written an appropriate response.
if ctx.Response().Committed {
return
}
var exc *Exception
exc, ok := err.(*Exception)
if !ok {
switch err {
case echo.ErrNotFound:
exc = ExcNotFound().Cause(err)
case echo.ErrMethodNotAllowed:
exc = ExcInvalidRequest().Cause(err)
case echo.ErrStatusRequestEntityTooLarge:
exc = ExcInvalidRequest().Cause(err)
case http.ErrHandlerTimeout:
exc = ExcRequestTimeout().Cause(err)
default: // Fallback.
exc = ExcServerGeneric().Cause(err)
}
}
if exc.status >= http.StatusInternalServerError {
self.observer.Error(ctx.Request().Context(), exc)
}
if ctx.Request().Method == http.MethodHead {
err = ctx.NoContent(exc.status)
} else {
if self.config.Environment != EnvDevelopment {
exc.Redact()
}
err = ctx.JSON(exc.status, exc)
}
if err != nil {
self.observer.Error(
ctx.Request().Context(), ErrExceptionHandlerGeneric().Withf("cannot return exception %s", exc).Wrap(err))
}
}