-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgatewayerrorhandler.go
More file actions
47 lines (41 loc) · 1.63 KB
/
gatewayerrorhandler.go
File metadata and controls
47 lines (41 loc) · 1.63 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
package prefab
import (
"context"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/genproto/googleapis/rpc/code"
"google.golang.org/protobuf/types/known/anypb"
)
// gatewayErrorHandler overrides the default error handling, to update the
// structure of the error response. The default error handler handles writing of
// headers and other tasks, so we intercept at the marshaling step.
//
// Default error handler: https://github.com/grpc-ecosystem/grpc-gateway/blob/0e7b2ebe117212ae651f0370d2753f237799afdf/runtime/errors.go#L93
// Proto representation of GRPC status which is returned by default: https://pkg.go.dev/google.golang.org/genproto/googleapis/rpc/status
func gatewayErrorHandler(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, r *http.Request, err error) {
m := &monkeypatcher{Marshaler: marshaler}
runtime.DefaultHTTPErrorHandler(ctx, mux, m, w, r, err)
}
// monkeyPatcher wraps a GRPC Gateway Marshaller and hijacks the marshalling
// of the grpc Status proto, to output our own error type.
type monkeypatcher struct {
runtime.Marshaler
}
func (m *monkeypatcher) Marshal(v interface{}) ([]byte, error) {
if s, ok := v.(grpcStatusProto); ok {
v = &CustomErrorResponse{
Code: s.GetCode(),
CodeName: code.Code_name[s.GetCode()],
Message: s.GetMessage(),
Details: s.GetDetails(),
}
}
return m.Marshaler.Marshal(v)
}
// Satisfies the interface exposed by the GRPC status proto, which in the
// context of the GRPC Gateway is a private type.
type grpcStatusProto interface {
GetCode() int32
GetMessage() string
GetDetails() []*anypb.Any
}