-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathresponse.go
135 lines (112 loc) · 3.27 KB
/
response.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package httphandler
import (
"fmt"
"net/http"
"runtime/debug"
"github.com/pkg/errors"
)
// Response is the base response interface type
type Response interface {
StatusCode() int
ContentType() string
Header() http.Header
Payload() interface{}
}
// StandardResponse implements the Response interface
type StandardResponse struct {
statusCode int
contentType string
header http.Header
payload interface{}
}
// NewStandardResponse returns a new StandardResponse
func NewStandardResponse(statusCode int, contentType string, payload interface{}) *StandardResponse {
return &StandardResponse{
statusCode: statusCode,
contentType: contentType,
payload: payload,
header: http.Header{},
}
}
// StatusCode returns the response status code
func (r *StandardResponse) StatusCode() int {
return r.statusCode
}
// ContentType returns the content type of the response
func (r *StandardResponse) ContentType() string {
return r.contentType
}
// Header returns the header object for the response
func (r *StandardResponse) Header() http.Header {
return r.header
}
// Payload returns the response payload
func (r *StandardResponse) Payload() interface{} {
return r.payload
}
// ErrorResponse extends the StandardResponse with fields for responding with and error
type ErrorResponse struct {
*StandardResponse
err error
msg errResp
stacktrace string
}
// Error returns the error message
func (e *ErrorResponse) Error() error {
return e.err
}
// Msg returns the errResp object that we can send back over the HTTP socket
func (e *ErrorResponse) Msg() errResp {
return e.msg
}
// StackTrace returns the stringified stacktrace of the error/panic (if exists)
func (e *ErrorResponse) StackTrace() string {
return e.stacktrace
}
type errResp struct {
ErrorMsg string `json:"error_message"`
ErrorID string `json:"error_id"`
StackTrace string `json:"stacktrace,omitempty"`
}
type stackTracer interface {
StackTrace() errors.StackTrace
}
// NewErrorResponse returns a new ErrorResponse with a status code and error set
// if err contains a stacktrace (if created with the errors package) we will stringify it and attach to the response.
func NewErrorResponse(statusCode int, err error) *ErrorResponse {
st := ""
t, ok := err.(stackTracer)
if ok {
st = fmt.Sprintf("%s:%+v", err.Error(), t.StackTrace())
} else {
st = string(debug.Stack())
}
m := errResp{
ErrorMsg: err.Error(),
StackTrace: st,
}
r := &ErrorResponse{
StandardResponse: NewStandardResponse(statusCode, "application/json", nil),
err: err,
msg: m,
stacktrace: st,
}
// r.err = err
return r
}
// JsonResponse is a StandardResponse but used as a shortcut for not having to specify the content type
type JsonResponse struct {
*StandardResponse
}
// NewJsonResponse returns a new JsonResponse
func NewJsonResponse(statusCode int, payload interface{}) *JsonResponse {
return &JsonResponse{NewStandardResponse(statusCode, "application/json", payload)}
}
// EmptyResponse is a StandardResponse but without payload
type EmptyResponse struct {
*StandardResponse
}
// NewEmptyResponse returns a new EmptyResponse with the status code set
func NewEmptyResponse(statusCode int) *EmptyResponse {
return &EmptyResponse{NewStandardResponse(statusCode, "", nil)}
}