diff --git a/Makefile b/Makefile index 3fd1777f54d..54112d090c7 100644 --- a/Makefile +++ b/Makefile @@ -44,9 +44,6 @@ SWAGGER_PLUGIN_FLAGS?= GOOGLEAPIS_DIR=third_party/googleapis OUTPUT_DIR=_output -RUNTIME_PROTO=internal/errors.proto -RUNTIME_GO=$(RUNTIME_PROTO:.proto=.pb.go) - OPENAPIV2_PROTO=protoc-gen-swagger/options/openapiv2.proto protoc-gen-swagger/options/annotations.proto OPENAPIV2_GO=$(OPENAPIV2_PROTO:.proto=.pb.go) @@ -143,20 +140,15 @@ SWAGGER_CODEGEN=swagger-codegen PROTOC_INC_PATH=$(dir $(shell which protoc))/../include -generate: $(RUNTIME_GO) - .SUFFIXES: .go .proto $(GO_PLUGIN): go build -o $(GO_PLUGIN) $(GO_PLUGIN_PKG) -$(RUNTIME_GO): $(RUNTIME_PROTO) $(GO_PLUGIN) - protoc -I $(PROTOC_INC_PATH) --plugin=$(GO_PLUGIN) -I. --go_out=$(PKGMAP),paths=source_relative:. $(RUNTIME_PROTO) - $(OPENAPIV2_GO): $(OPENAPIV2_PROTO) $(GO_PLUGIN) protoc -I $(PROTOC_INC_PATH) --plugin=$(GO_PLUGIN) -I. --go_out=$(PKGMAP),paths=source_relative:. $(OPENAPIV2_PROTO) -$(GATEWAY_PLUGIN): $(RUNTIME_GO) $(GATEWAY_PLUGIN_SRC) +$(GATEWAY_PLUGIN): $(GATEWAY_PLUGIN_SRC) go build -o $@ $(GATEWAY_PLUGIN_PKG) $(SWAGGER_PLUGIN): $(SWAGGER_PLUGIN_SRC) $(OPENAPIV2_GO) @@ -234,11 +226,11 @@ changelog: --future-release=v1.14.4 lint: golint --set_exit_status ./runtime - golint --set_exit_status ././internal/utilities/... + golint --set_exit_status ./internal/utilities/... golint --set_exit_status ./protoc-gen-grpc-gateway/... golint --set_exit_status ./protoc-gen-swagger/... go vet ./runtime || true - go vet ././internal/utilities/... + go vet ./internal/utilities/... go vet ./protoc-gen-grpc-gateway/... go vet ./protoc-gen-swagger/... diff --git a/examples/internal/clients/responsebody/api/swagger.yaml b/examples/internal/clients/responsebody/api/swagger.yaml index 59d02a7a163..4d9c6d29f51 100644 --- a/examples/internal/clients/responsebody/api/swagger.yaml +++ b/examples/internal/clients/responsebody/api/swagger.yaml @@ -50,7 +50,7 @@ paths: result: $ref: "#/definitions/examplepbResponseBodyOutResponse" error: - $ref: "#/definitions/runtimeStreamError" + $ref: "#/definitions/rpcStatus" title: "Stream result of examplepbResponseBodyOut" default: description: "An unexpected error response" @@ -216,49 +216,28 @@ definitions: type: "array" items: $ref: "#/definitions/protobufAny" - runtimeStreamError: - type: "object" - properties: - grpc_code: - type: "integer" - format: "int32" - http_code: - type: "integer" - format: "int32" - message: - type: "string" - http_status: - type: "string" - details: - type: "array" - items: - $ref: "#/definitions/protobufAny" example: - http_code: 6 - http_status: "http_status" + code: 0 details: - value: "value" type_url: "type_url" - value: "value" type_url: "type_url" message: "message" - grpc_code: 0 Stream result of examplepbResponseBodyOut: properties: result: $ref: "#/definitions/examplepbResponseBodyOutResponse" error: - $ref: "#/definitions/runtimeStreamError" + $ref: "#/definitions/rpcStatus" example: result: data: "data" error: - http_code: 6 - http_status: "http_status" + code: 0 details: - value: "value" type_url: "type_url" - value: "value" type_url: "type_url" message: "message" - grpc_code: 0 diff --git a/examples/internal/clients/responsebody/docs/StreamResultOfExamplepbResponseBodyOut.md b/examples/internal/clients/responsebody/docs/StreamResultOfExamplepbResponseBodyOut.md index 8cf8014022a..608ad5047c3 100644 --- a/examples/internal/clients/responsebody/docs/StreamResultOfExamplepbResponseBodyOut.md +++ b/examples/internal/clients/responsebody/docs/StreamResultOfExamplepbResponseBodyOut.md @@ -4,7 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Result** | [***ExamplepbResponseBodyOutResponse**](examplepbResponseBodyOutResponse.md) | | [optional] [default to null] -**Error_** | [***RuntimeStreamError**](runtimeStreamError.md) | | [optional] [default to null] +**Error_** | [***RpcStatus**](rpcStatus.md) | | [optional] [default to null] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/examples/internal/clients/responsebody/model_stream_result_of_examplepb_response_body_out.go b/examples/internal/clients/responsebody/model_stream_result_of_examplepb_response_body_out.go index 4fc188ba216..20893eec6bd 100644 --- a/examples/internal/clients/responsebody/model_stream_result_of_examplepb_response_body_out.go +++ b/examples/internal/clients/responsebody/model_stream_result_of_examplepb_response_body_out.go @@ -11,5 +11,5 @@ package responsebody type StreamResultOfExamplepbResponseBodyOut struct { Result *ExamplepbResponseBodyOutResponse `json:"result,omitempty"` - Error_ *RuntimeStreamError `json:"error,omitempty"` + Error_ *RpcStatus `json:"error,omitempty"` } diff --git a/examples/internal/proto/examplepb/response_body_service.swagger.json b/examples/internal/proto/examplepb/response_body_service.swagger.json index 31f2fc59788..55d830a3a18 100644 --- a/examples/internal/proto/examplepb/response_body_service.swagger.json +++ b/examples/internal/proto/examplepb/response_body_service.swagger.json @@ -57,7 +57,7 @@ "$ref": "#/definitions/examplepbResponseBodyOutResponse" }, "error": { - "$ref": "#/definitions/runtimeStreamError" + "$ref": "#/definitions/rpcStatus" } }, "title": "Stream result of examplepbResponseBodyOut" @@ -239,31 +239,6 @@ } } } - }, - "runtimeStreamError": { - "type": "object", - "properties": { - "grpc_code": { - "type": "integer", - "format": "int32" - }, - "http_code": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - }, - "http_status": { - "type": "string" - }, - "details": { - "type": "array", - "items": { - "$ref": "#/definitions/protobufAny" - } - } - } } } } diff --git a/examples/internal/proto/examplepb/stream.swagger.json b/examples/internal/proto/examplepb/stream.swagger.json index b54ec910a5e..6acfa64f7a9 100644 --- a/examples/internal/proto/examplepb/stream.swagger.json +++ b/examples/internal/proto/examplepb/stream.swagger.json @@ -24,7 +24,7 @@ "$ref": "#/definitions/examplepbABitOfEverything" }, "error": { - "$ref": "#/definitions/runtimeStreamError" + "$ref": "#/definitions/rpcStatus" } }, "title": "Stream result of examplepbABitOfEverything" @@ -88,7 +88,7 @@ "$ref": "#/definitions/subStringMessage" }, "error": { - "$ref": "#/definitions/runtimeStreamError" + "$ref": "#/definitions/rpcStatus" } }, "title": "Stream result of subStringMessage" @@ -395,31 +395,6 @@ } } }, - "runtimeStreamError": { - "type": "object", - "properties": { - "grpc_code": { - "type": "integer", - "format": "int32" - }, - "http_code": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - }, - "http_status": { - "type": "string" - }, - "details": { - "type": "array", - "items": { - "$ref": "#/definitions/protobufAny" - } - } - } - }, "subStringMessage": { "type": "object", "properties": { diff --git a/internal/BUILD.bazel b/internal/BUILD.bazel deleted file mode 100644 index 2a4111eab3d..00000000000 --- a/internal/BUILD.bazel +++ /dev/null @@ -1,23 +0,0 @@ -load("@rules_proto//proto:defs.bzl", "proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") - -package(default_visibility = ["//visibility:public"]) - -proto_library( - name = "internal_proto", - srcs = ["errors.proto"], - deps = ["@com_google_protobuf//:any_proto"], -) - -go_proto_library( - name = "internal_go_proto", - importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal", - proto = ":internal_proto", -) - -go_library( - name = "go_default_library", - embed = [":internal_go_proto"], - importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal", -) diff --git a/internal/errors.pb.go b/internal/errors.pb.go deleted file mode 100644 index 5a2faa56e1d..00000000000 --- a/internal/errors.pb.go +++ /dev/null @@ -1,196 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.21.0 -// protoc v3.10.1 -// source: internal/errors.proto - -package internal - -import ( - proto "github.com/golang/protobuf/proto" - any "github.com/golang/protobuf/ptypes/any" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -// StreamError is a response type which is returned when -// streaming rpc returns an error. -type StreamError struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - GrpcCode int32 `protobuf:"varint,1,opt,name=grpc_code,json=grpcCode,proto3" json:"grpc_code,omitempty"` - HttpCode int32 `protobuf:"varint,2,opt,name=http_code,json=httpCode,proto3" json:"http_code,omitempty"` - Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` - HttpStatus string `protobuf:"bytes,4,opt,name=http_status,json=httpStatus,proto3" json:"http_status,omitempty"` - Details []*any.Any `protobuf:"bytes,5,rep,name=details,proto3" json:"details,omitempty"` -} - -func (x *StreamError) Reset() { - *x = StreamError{} - if protoimpl.UnsafeEnabled { - mi := &file_internal_errors_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StreamError) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StreamError) ProtoMessage() {} - -func (x *StreamError) ProtoReflect() protoreflect.Message { - mi := &file_internal_errors_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StreamError.ProtoReflect.Descriptor instead. -func (*StreamError) Descriptor() ([]byte, []int) { - return file_internal_errors_proto_rawDescGZIP(), []int{0} -} - -func (x *StreamError) GetGrpcCode() int32 { - if x != nil { - return x.GrpcCode - } - return 0 -} - -func (x *StreamError) GetHttpCode() int32 { - if x != nil { - return x.HttpCode - } - return 0 -} - -func (x *StreamError) GetMessage() string { - if x != nil { - return x.Message - } - return "" -} - -func (x *StreamError) GetHttpStatus() string { - if x != nil { - return x.HttpStatus - } - return "" -} - -func (x *StreamError) GetDetails() []*any.Any { - if x != nil { - return x.Details - } - return nil -} - -var File_internal_errors_proto protoreflect.FileDescriptor - -var file_internal_errors_proto_rawDesc = []byte{ - 0x0a, 0x15, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, - 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x1a, 0x19, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, - 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb2, 0x01, 0x0a, 0x0b, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x70, 0x63, - 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x67, 0x72, 0x70, - 0x63, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, - 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x43, 0x6f, - 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x68, 0x74, 0x74, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2e, 0x0a, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0x0a, 0x5a, - 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var ( - file_internal_errors_proto_rawDescOnce sync.Once - file_internal_errors_proto_rawDescData = file_internal_errors_proto_rawDesc -) - -func file_internal_errors_proto_rawDescGZIP() []byte { - file_internal_errors_proto_rawDescOnce.Do(func() { - file_internal_errors_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_errors_proto_rawDescData) - }) - return file_internal_errors_proto_rawDescData -} - -var file_internal_errors_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_internal_errors_proto_goTypes = []interface{}{ - (*StreamError)(nil), // 0: grpc.gateway.runtime.StreamError - (*any.Any)(nil), // 1: google.protobuf.Any -} -var file_internal_errors_proto_depIdxs = []int32{ - 1, // 0: grpc.gateway.runtime.StreamError.details:type_name -> google.protobuf.Any - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_internal_errors_proto_init() } -func file_internal_errors_proto_init() { - if File_internal_errors_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_internal_errors_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StreamError); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_internal_errors_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_internal_errors_proto_goTypes, - DependencyIndexes: file_internal_errors_proto_depIdxs, - MessageInfos: file_internal_errors_proto_msgTypes, - }.Build() - File_internal_errors_proto = out.File - file_internal_errors_proto_rawDesc = nil - file_internal_errors_proto_goTypes = nil - file_internal_errors_proto_depIdxs = nil -} diff --git a/internal/errors.proto b/internal/errors.proto deleted file mode 100644 index 55f42ce63ec..00000000000 --- a/internal/errors.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; -package grpc.gateway.runtime; -option go_package = "internal"; - -import "google/protobuf/any.proto"; - -// StreamError is a response type which is returned when -// streaming rpc returns an error. -message StreamError { - int32 grpc_code = 1; - int32 http_code = 2; - string message = 3; - string http_status = 4; - repeated google.protobuf.Any details = 5; -} diff --git a/protoc-gen-swagger/internal/genswagger/BUILD.bazel b/protoc-gen-swagger/internal/genswagger/BUILD.bazel index 233c5b8fa88..a3295f7c772 100644 --- a/protoc-gen-swagger/internal/genswagger/BUILD.bazel +++ b/protoc-gen-swagger/internal/genswagger/BUILD.bazel @@ -14,7 +14,6 @@ go_library( ], importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-swagger/internal/genswagger", deps = [ - "//internal:go_default_library", "//internal/casing:go_default_library", "//internal/descriptor:go_default_library", "//internal/generator:go_default_library", diff --git a/protoc-gen-swagger/internal/genswagger/generator.go b/protoc-gen-swagger/internal/genswagger/generator.go index 4d9610578cf..b1f922de7f1 100644 --- a/protoc-gen-swagger/internal/genswagger/generator.go +++ b/protoc-gen-swagger/internal/genswagger/generator.go @@ -15,7 +15,6 @@ import ( protocdescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" plugin "github.com/golang/protobuf/protoc-gen-go/plugin" "github.com/golang/protobuf/ptypes/any" - "github.com/grpc-ecosystem/grpc-gateway/v2/internal" "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor" gen "github.com/grpc-ecosystem/grpc-gateway/v2/internal/generator" swagger_options "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-swagger/options" @@ -218,18 +217,16 @@ func (g *generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGenerato return files, nil } -// AddErrorDefs Adds grpc.gateway.runtime.StreamError, google.rpc.Status, and google.protobuf.Any +// AddErrorDefs Adds google.rpc.Status and google.protobuf.Any // to registry (used for error-related API responses) func AddErrorDefs(reg *descriptor.Registry) error { // load internal protos any := fileDescriptorProtoForMessage(&any.Any{}) status := fileDescriptorProtoForMessage(&spb.Status{}) - streamError := fileDescriptorProtoForMessage(&internal.StreamError{}) return reg.Load(&plugin.CodeGeneratorRequest{ ProtoFile: []*protocdescriptor.FileDescriptorProto{ any, status, - streamError, }, }) } diff --git a/protoc-gen-swagger/internal/genswagger/template.go b/protoc-gen-swagger/internal/genswagger/template.go index 71fc606a01b..fa032197acd 100644 --- a/protoc-gen-swagger/internal/genswagger/template.go +++ b/protoc-gen-swagger/internal/genswagger/template.go @@ -260,18 +260,6 @@ func findServicesMessagesAndEnumerations(s []*descriptor.Service, reg *descripto if !skipRenderingRef(meth.ResponseType.FQMN()) { m[swgRspName] = meth.ResponseType - if meth.GetServerStreaming() { - streamError, runtimeStreamError, err := lookupMsgAndSwaggerName(".grpc.gateway.runtime", "StreamError", reg) - if err != nil { - glog.Error(err) - } else { - glog.V(1).Infof("StreamError: %v", streamError) - glog.V(1).Infof("StreamError FQMN: %s", runtimeStreamError) - m[runtimeStreamError] = streamError - findNestedMessagesAndEnumerations(streamError, reg, m, e) - } - ms[swgRspName] = meth.ResponseType - } } findNestedMessagesAndEnumerations(meth.ResponseType, reg, m, e) } @@ -934,13 +922,13 @@ func renderServices(services []*descriptor.Service, paths swaggerPathsObject, re }, }, } - streamErrDef, hasStreamError := fullyQualifiedNameToSwaggerName(".grpc.gateway.runtime.StreamError", reg) - if hasStreamError { + statusDef, hasStatus := fullyQualifiedNameToSwaggerName(".google.rpc.Status", reg) + if hasStatus { props = append(props, keyVal{ Key: "error", Value: swaggerSchemaObject{ schemaCore: schemaCore{ - Ref: fmt.Sprintf("#/definitions/%s", streamErrDef)}, + Ref: fmt.Sprintf("#/definitions/%s", statusDef)}, }, }) } diff --git a/protoc-gen-swagger/internal/genswagger/template_test.go b/protoc-gen-swagger/internal/genswagger/template_test.go index 5c65ed52972..6c954a7e5a5 100644 --- a/protoc-gen-swagger/internal/genswagger/template_test.go +++ b/protoc-gen-swagger/internal/genswagger/template_test.go @@ -1270,7 +1270,7 @@ func TestApplyTemplateRequestWithClientStreaming(t *testing.T) { } // Only ExampleMessage must be present, not NestedMessage - if want, got, name := 4, len(result.Definitions), "len(Definitions)"; !reflect.DeepEqual(got, want) { + if want, got, name := 3, len(result.Definitions), "len(Definitions)"; !reflect.DeepEqual(got, want) { t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want) } if _, ok := result.Paths["/v1/echo"].Post.Responses["200"]; !ok { @@ -1303,7 +1303,7 @@ func TestApplyTemplateRequestWithClientStreaming(t *testing.T) { t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want) } err := errorProperty.Value.(swaggerSchemaObject) - if want, got, name := "#/definitions/runtimeStreamError", err.Ref, `((*(StreamDefinitions["exampleExampleMessage"].Properties))[0].Value.(swaggerSchemaObject)).Ref`; !reflect.DeepEqual(got, want) { + if want, got, name := "#/definitions/rpcStatus", err.Ref, `((*(StreamDefinitions["exampleExampleMessage"].Properties))[0].Value.(swaggerSchemaObject)).Ref`; !reflect.DeepEqual(got, want) { t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want) } } diff --git a/runtime/BUILD.bazel b/runtime/BUILD.bazel index 3f0c0395b9a..745fa692547 100644 --- a/runtime/BUILD.bazel +++ b/runtime/BUILD.bazel @@ -25,13 +25,11 @@ go_library( ], importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/runtime", deps = [ - "//internal:go_default_library", "//internal/utilities:go_default_library", "@com_github_golang_protobuf//descriptor:go_default_library_gen", "@com_github_golang_protobuf//jsonpb:go_default_library_gen", "@com_github_golang_protobuf//proto:go_default_library", "@go_googleapis//google/api:httpbody_go_proto", - "@io_bazel_rules_go//proto/wkt:any_go_proto", "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", "@io_bazel_rules_go//proto/wkt:duration_go_proto", "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", @@ -64,7 +62,6 @@ go_test( ], embed = [":go_default_library"], deps = [ - "//internal:go_default_library", "//internal/utilities:go_default_library", "//runtime/internal/examplepb:go_default_library", "@com_github_golang_protobuf//jsonpb:go_default_library_gen", diff --git a/runtime/handler.go b/runtime/handler.go index f058ba4cb71..82a476c6536 100644 --- a/runtime/handler.go +++ b/runtime/handler.go @@ -2,19 +2,17 @@ package runtime import ( "context" - "errors" "fmt" "io" "net/http" "net/textproto" "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/v2/internal" + "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" ) -var errEmptyResponse = errors.New("empty response") - // ForwardResponseStream forwards the stream from gRPC server to REST client. func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { f, ok := w.(http.Flusher) @@ -64,7 +62,7 @@ func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshal var buf []byte switch { case resp == nil: - buf, err = marshaler.Marshal(errorChunk(streamError(ctx, mux.streamErrorHandler, errEmptyResponse))) + buf, err = marshaler.Marshal(errorChunk(status.New(codes.Internal, "empty response"))) default: result := map[string]interface{}{"result": resp} if rb, ok := resp.(responseBody); ok { @@ -181,11 +179,11 @@ func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, re } func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error) { - serr := streamError(ctx, mux.streamErrorHandler, err) + st := status.Convert(err) if !wroteHeader { - w.WriteHeader(int(serr.HttpCode)) + w.WriteHeader(HTTPStatusFromCode(st.Code())) } - buf, merr := marshaler.Marshal(errorChunk(serr)) + buf, merr := marshaler.Marshal(errorChunk(st)) if merr != nil { grpclog.Infof("Failed to marshal an error: %v", merr) return @@ -196,17 +194,6 @@ func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, mar } } -// streamError returns the payload for the final message in a response stream -// that represents the given err. -func streamError(ctx context.Context, errHandler StreamErrorHandlerFunc, err error) *StreamError { - serr := errHandler(ctx, err) - if serr != nil { - return serr - } - // TODO: log about misbehaving stream error handler? - return DefaultHTTPStreamErrorHandler(ctx, err) -} - -func errorChunk(err *StreamError) map[string]proto.Message { - return map[string]proto.Message{"error": (*internal.StreamError)(err)} +func errorChunk(st *status.Status) map[string]proto.Message { + return map[string]proto.Message{"error": st.Proto()} } diff --git a/runtime/handler_test.go b/runtime/handler_test.go index bf2a9e922c6..270cfab9cc9 100644 --- a/runtime/handler_test.go +++ b/runtime/handler_test.go @@ -9,7 +9,6 @@ import ( "testing" "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/v2/internal" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" pb "github.com/grpc-ecosystem/grpc-gateway/v2/runtime/internal/examplepb" "google.golang.org/grpc" @@ -119,16 +118,9 @@ func TestForwardResponseStream(t *testing.T) { // Skip non-stream errors t.Skip("checking error encodings") } - st, _ := status.FromError(msg.err) - httpCode := runtime.HTTPStatusFromCode(st.Code()) + st := status.Convert(msg.err) b, err := marshaler.Marshal(map[string]proto.Message{ - "error": &internal.StreamError{ - GrpcCode: int32(st.Code()), - HttpCode: int32(httpCode), - Message: st.Message(), - HttpStatus: http.StatusText(httpCode), - Details: st.Proto().GetDetails(), - }, + "error": st.Proto(), }) if err != nil { t.Errorf("marshaler.Marshal() failed %v", err) diff --git a/runtime/mux.go b/runtime/mux.go index b35708616db..eb7e435365e 100644 --- a/runtime/mux.go +++ b/runtime/mux.go @@ -34,7 +34,6 @@ type ServeMux struct { incomingHeaderMatcher HeaderMatcherFunc outgoingHeaderMatcher HeaderMatcherFunc metadataAnnotators []func(context.Context, *http.Request) metadata.MD - streamErrorHandler StreamErrorHandlerFunc protoErrorHandler ProtoErrorHandlerFunc disablePathLengthFallback bool lastMatchWins bool @@ -129,20 +128,6 @@ func WithDisablePathLengthFallback() ServeMuxOption { } } -// WithStreamErrorHandler returns a ServeMuxOption that will use the given custom stream -// error handler, which allows for customizing the error trailer for server-streaming -// calls. -// -// For stream errors that occur before any response has been written, the mux's -// ProtoErrorHandler will be invoked. However, once data has been written, the errors must -// be handled differently: they must be included in the response body. The response body's -// final message will include the error details returned by the stream error handler. -func WithStreamErrorHandler(fn StreamErrorHandlerFunc) ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.streamErrorHandler = fn - } -} - // WithLastMatchWins returns a ServeMuxOption that will enable "last // match wins" behavior, where if multiple path patterns match a // request path, the last one defined in the .proto file will be used. @@ -158,7 +143,6 @@ func NewServeMux(opts ...ServeMuxOption) *ServeMux { handlers: make(map[string][]handler), forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0), marshalers: makeMarshalerMIMERegistry(), - streamErrorHandler: DefaultHTTPStreamErrorHandler, } for _, opt := range opts { diff --git a/runtime/proto_errors.go b/runtime/proto_errors.go index 9a46f50d00b..b0cf0d0bb3f 100644 --- a/runtime/proto_errors.go +++ b/runtime/proto_errors.go @@ -5,21 +5,11 @@ import ( "io" "net/http" - "github.com/golang/protobuf/ptypes/any" - "github.com/grpc-ecosystem/grpc-gateway/v2/internal" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/status" ) -// StreamErrorHandlerFunc accepts an error as a gRPC error generated via status package and translates it into a -// a proto struct used to represent error at the end of a stream. -type StreamErrorHandlerFunc func(context.Context, error) *StreamError - -// StreamError is the payload for the final message in a server stream in the event that the server returns an -// error after a response message has already been sent. -type StreamError internal.StreamError - // ProtoErrorHandlerFunc handles the error as a gRPC error generated via status package and replies to the request. type ProtoErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error) @@ -78,29 +68,3 @@ func DefaultHTTPProtoErrorHandler(ctx context.Context, mux *ServeMux, marshaler handleForwardResponseTrailer(w, md) } - -// DefaultHTTPStreamErrorHandler converts the given err into a *StreamError via -// default logic. -// -// It extracts the gRPC status from err if possible. The fields of the status are -// used to populate the returned StreamError, and the HTTP status code is derived -// from the gRPC code via HTTPStatusFromCode. If the given err does not contain a -// gRPC status, an "Unknown" gRPC code is used and "Internal Server Error" HTTP code. -func DefaultHTTPStreamErrorHandler(_ context.Context, err error) *StreamError { - grpcCode := codes.Unknown - grpcMessage := err.Error() - var grpcDetails []*any.Any - if s, ok := status.FromError(err); ok { - grpcCode = s.Code() - grpcMessage = s.Message() - grpcDetails = s.Proto().GetDetails() - } - httpCode := HTTPStatusFromCode(grpcCode) - return &StreamError{ - GrpcCode: int32(grpcCode), - HttpCode: int32(httpCode), - Message: grpcMessage, - HttpStatus: http.StatusText(httpCode), - Details: grpcDetails, - } -}