Index: server/prpc/method.go |
diff --git a/server/prpc/method.go b/server/prpc/method.go |
index aa0b5c2f61779991a2fc375ca356a5b8a9974e91..b88599dbf58c7972d23a8e80f6535021adf04154 100644 |
--- a/server/prpc/method.go |
+++ b/server/prpc/method.go |
@@ -5,15 +5,14 @@ |
package prpc |
import ( |
- "fmt" |
"net/http" |
"github.com/golang/protobuf/proto" |
- "github.com/julienschmidt/httprouter" |
"golang.org/x/net/context" |
"google.golang.org/grpc" |
+ "google.golang.org/grpc/codes" |
- "github.com/luci/luci-go/server/middleware" |
+ "github.com/luci/luci-go/common/grpcutil" |
) |
type method struct { |
@@ -21,72 +20,46 @@ type method struct { |
desc grpc.MethodDesc |
} |
-func (m *method) Name() string { |
- return m.desc.MethodName |
-} |
- |
-// Handle decodes an input protobuf message from the HTTP request, |
+// handle decodes an input protobuf message from the HTTP request, |
// delegates RPC handling to the inner implementation and |
// encodes the output message back to the HTTP response. |
// |
// If the inner handler returns an error, HTTP status is determined using |
-// ErrorStatus. |
-// If the status is http.StatusInternalServerError, only "Internal server error" |
-// is printed. |
-// All errors with status >= 500 are logged. |
-func (m *method) Handle(c context.Context, w http.ResponseWriter, r *http.Request, _ httprouter.Params) { |
- if err := m.handle(c, w, r); err != nil { |
- writeError(c, w, err) |
- } |
-} |
- |
-// handle decodes an input protobuf message from the HTTP request, |
-// delegates RPC handling to the inner implementation and |
-// encodes the output message back to the HTTP response. |
-func (m *method) handle(c context.Context, w http.ResponseWriter, r *http.Request) *httpError { |
+// errorStatus. |
+// Prints only "Internal server error" if the code is Internal. |
+// Logs the error if code is Internal or Unknown. |
+func (m *method) handle(c context.Context, w http.ResponseWriter, r *http.Request) *response { |
defer r.Body.Close() |
- format, err := responseFormat(r.Header.Get(headerAccept)) |
- if err != nil { |
- return err |
+ |
+ format, perr := responseFormat(r.Header.Get(headerAccept)) |
+ if perr != nil { |
+ return respondProtocolError(perr) |
} |
- c, rawErr := parseHeader(c, r.Header) |
- if rawErr != nil { |
- return withStatus(rawErr, http.StatusBadRequest) |
+ c, err := parseHeader(c, r.Header) |
+ if err != nil { |
+ return respondProtocolError(withStatus(err, http.StatusBadRequest)) |
} |
- res, rawErr := m.desc.Handler(m.service.impl, c, func(msg interface{}) error { |
- if msg == nil { |
- panicf("cannot decode to nil") |
+ out, err := m.desc.Handler(m.service.impl, c, func(in interface{}) error { |
+ if in == nil { |
+ return grpcutil.Errf(codes.Internal, "input message is nil") |
} |
// Do not collapse it to one line. There is implicit err type conversion. |
- if err := readMessage(r, msg.(proto.Message)); err != nil { |
- return err |
+ if perr := readMessage(r, in.(proto.Message)); perr != nil { |
+ return perr |
} |
return nil |
}) |
- if rawErr != nil { |
- if err, ok := rawErr.(*httpError); ok { |
- return err |
+ if err != nil { |
+ if perr, ok := err.(*protocolError); ok { |
+ return respondProtocolError(perr) |
} |
- return withStatus(rawErr, ErrorStatus(rawErr)) |
- } |
- if res == nil { |
- return m.internalServerError("service returned nil message") |
- } |
- if err := writeMessage(w, res.(proto.Message), format); err != nil { |
- return m.internalServerError("could not respond: %s", err) |
+ return errResponse(errorCode(err), 0, grpc.ErrorDesc(err)) |
} |
- return nil |
-} |
- |
-// InstallHandlers installs a POST HTTP handlers at /prpc/{service_name}/{method_name}. |
-func (m *method) InstallHandlers(r *httprouter.Router, base middleware.Base) { |
- path := fmt.Sprintf("/prpc/%s/%s", m.service.Name(), m.Name()) |
- r.POST(path, base(m.Handle)) |
-} |
-func (m *method) internalServerError(format string, a ...interface{}) *httpError { |
- format = fmt.Sprintf("%s.%s: ", m.service.Name(), m.Name()) + format |
- return errorf(http.StatusInternalServerError, format, a...) |
+ if out == nil { |
+ return errResponse(codes.Internal, 0, "service returned nil message") |
+ } |
+ return respondMessage(out.(proto.Message), format) |
} |