Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / github.com / grpc-ecosystem / grpc-gateway / runtime / proto_errors.go
1 package runtime
2
3 import (
4         "io"
5         "net/http"
6
7         "context"
8         "google.golang.org/grpc/codes"
9         "google.golang.org/grpc/grpclog"
10         "google.golang.org/grpc/status"
11 )
12
13 // ProtoErrorHandlerFunc handles the error as a gRPC error generated via status package and replies to the request.
14 type ProtoErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error)
15
16 var _ ProtoErrorHandlerFunc = DefaultHTTPProtoErrorHandler
17
18 // DefaultHTTPProtoErrorHandler is an implementation of HTTPError.
19 // If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode.
20 // If otherwise, it replies with http.StatusInternalServerError.
21 //
22 // The response body returned by this function is a Status message marshaled by a Marshaler.
23 //
24 // Do not set this function to HTTPError variable directly, use WithProtoErrorHandler option instead.
25 func DefaultHTTPProtoErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
26         // return Internal when Marshal failed
27         const fallback = `{"code": 13, "message": "failed to marshal error message"}`
28
29         s, ok := status.FromError(err)
30         if !ok {
31                 s = status.New(codes.Unknown, err.Error())
32         }
33
34         w.Header().Del("Trailer")
35
36         contentType := marshaler.ContentType()
37         // Check marshaler on run time in order to keep backwards compatability
38         // An interface param needs to be added to the ContentType() function on 
39         // the Marshal interface to be able to remove this check
40         if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok {
41                 pb := s.Proto()
42                 contentType = httpBodyMarshaler.ContentTypeFromMessage(pb)
43         }
44         w.Header().Set("Content-Type", contentType)
45
46         buf, merr := marshaler.Marshal(s.Proto())
47         if merr != nil {
48                 grpclog.Infof("Failed to marshal error message %q: %v", s.Proto(), merr)
49                 w.WriteHeader(http.StatusInternalServerError)
50                 if _, err := io.WriteString(w, fallback); err != nil {
51                         grpclog.Infof("Failed to write response: %v", err)
52                 }
53                 return
54         }
55
56         md, ok := ServerMetadataFromContext(ctx)
57         if !ok {
58                 grpclog.Infof("Failed to extract ServerMetadata from context")
59         }
60
61         handleForwardResponseServerMetadata(w, mux, md)
62         handleForwardResponseTrailerHeader(w, md)
63         st := HTTPStatusFromCode(s.Code())
64         w.WriteHeader(st)
65         if _, err := w.Write(buf); err != nil {
66                 grpclog.Infof("Failed to write response: %v", err)
67         }
68
69         handleForwardResponseTrailer(w, md)
70 }