grpc-rest 0.1.21 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '090bea208182dd067a0a1f0347e9cb4484610dca9a7a4f1c2f7689fa216d40e8'
4
- data.tar.gz: 3695746b75dcbba972e88249ad2785551d7e0e4fbd9d8a01140496dfa4f2a002
3
+ metadata.gz: b4e105820176e2fb387f9ff63ae82a086de8d1b291d372f8e8ba3d38dfc34859
4
+ data.tar.gz: 1e480bc608d0524821ba06d408681830294ab34c9e36bd330b881f48128f8e33
5
5
  SHA512:
6
- metadata.gz: 963b26c2d6141a20a3739341bd564005000a7dfdbe42a0bee3becffd04bc1f7d455a692135f21037399e12431c0bba91e73c17b4aa0d4bef6c75944fef4d2782
7
- data.tar.gz: eaad993e480c9a9e7d05c55dedd4a7de06712666b3cd5601b6566bcd5da955a5b30e7528562b117b35297862cc4a6ad3930c8aabcc5eb81bbba6417ab3babae5
6
+ metadata.gz: c8118e6cbb88e44bc3577e66c4639f3e5b87ff18515f1c27d9dd5d458caacac52030f39afbd4a108b2009115b7e28ce9c9c7a810419517f700894538febfe3de
7
+ data.tar.gz: e591ab5d4d0481048f4e61814d1552d83c782f91191fd4f3f1aa430bacfc257aaac2ff3225152767b5acb7e13f1dcc75c42cb86ae93919d6b3cfc483b7bea53d
data/CHANGELOG CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## UNRELEASED
9
9
 
10
+ # 0.1.24 - 2024-12-09
11
+ - Log error backtraces.
12
+
13
+ # 0.1.23 - 2024-11-25
14
+ - Fix: Return a 400 status code when payload is invalid JSON
15
+
16
+ # 0.1.22 - 2024-10-31
17
+ - Fix: calling `fail!` in gruf Interceptors was failing with an unrelated exception.
18
+
10
19
  # 0.1.21 - 2024-09-12
11
20
  - Feature: Support gruf Interceptors.
12
21
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grpc-rest (0.1.21)
4
+ grpc-rest (0.1.22)
5
5
  grpc
6
6
  rails (>= 6.0)
7
7
 
data/README.md CHANGED
@@ -154,9 +154,24 @@ service MyService {
154
154
 
155
155
  ## Gruf Interceptors
156
156
 
157
- grpc-rest supports [gruf](https://github.com/bigcommerce/gruf) Interceptors. As long as you're not using a custom interceptor
157
+ grpc-rest supports [gruf](https://github.com/bigcommerce/gruf) Interceptors through a custom `GrpcRest::BaseInterceptor` class. As long as you're not using a custom interceptor
158
158
  registry, your interceptors will be called normally around the controller.
159
159
 
160
+ ```ruby
161
+ require 'grpc_rest/base_interceptor'
162
+
163
+ module Interceptors
164
+ # Interceptor for catching errors from controllers
165
+ class ErrorInterceptor < GrpcRest::BaseInterceptor
166
+
167
+ def call
168
+ # Your code here
169
+ end
170
+
171
+ end
172
+ end
173
+ ```
174
+
160
175
  ## To Do
161
176
 
162
177
  * Replace Go implementation with Ruby (+ executable)
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gruf'
4
+
5
+ module GrpcRest
6
+ # Fixes an issue with the fail! method since the active call is not instantiated yet.
7
+ # Overloads https://github.com/bigcommerce/gruf/blob/main/lib/gruf/errors/helpers.rb#L34
8
+ class BaseInterceptor < ::Gruf::Interceptors::ServerInterceptor
9
+ def fail!(error_code, _app_code, message = 'unknown error', metadata = {})
10
+ raise grpc_error(error_code, message.to_s, metadata)
11
+ end
12
+
13
+ private
14
+
15
+ # Ported from https://github.com/flipp-oss/grpc-rest/blob/main/lib/grpc_rest.rb#L142
16
+ def grpc_error(error_code, message, metadata)
17
+ case error_code
18
+ when :ok
19
+ GRPC::Ok.new(message, metadata)
20
+ when 499
21
+ GRPC::Cancelled.new(message, metadata)
22
+ when :bad_request, :invalid_argument
23
+ GRPC::InvalidArgument.new(message, metadata)
24
+ when :gateway_timeout
25
+ GRPC::DeadlineExceeded.new(message, metadata)
26
+ when :not_found
27
+ GRPC::NotFound.new(message, metadata)
28
+ when :conflict
29
+ GRPC::AlreadyExists.new(message, metadata)
30
+ when :forbidden
31
+ GRPC::PermissionDenied.new(message, metadata)
32
+ when :unauthorized
33
+ GRPC::Unauthenticated.new(message, metadata)
34
+ when :too_many_requests
35
+ GRPC::ResourceExhausted.new(message, metadata)
36
+ when :not_implemented
37
+ GRPC::Unimplemented.new(message, metadata)
38
+ when :service_unavailable
39
+ GRPC::Unavailable.new(message, metadata)
40
+ else
41
+ GRPC::Internal.new(message, metadata)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,3 @@
1
1
  module GrpcRest
2
- VERSION = '0.1.21'
2
+ VERSION = '0.1.24'
3
3
  end
@@ -63,7 +63,7 @@ class {{.ControllerName}}Controller < ActionController::Base
63
63
  rescue_from GRPC::BadStatus do |e|
64
64
  render json: GrpcRest.error_msg(e), status: GrpcRest.grpc_http_status(e.code)
65
65
  end
66
- rescue_from Google::Protobuf::TypeError do |e|
66
+ rescue_from ActionDispatch::Http::Parameters::ParseError, Google::Protobuf::TypeError do |e|
67
67
  render json: GrpcRest.error_msg(e), status: :bad_request
68
68
  end
69
69
  METHOD_PARAM_MAP = {
@@ -102,20 +102,22 @@ func ProcessService(service *descriptorpb.ServiceDescriptorProto, pkg string) (F
102
102
  return FileResult{}, routes, err
103
103
  }
104
104
  restOpts, err := ExtractRestOptions(m)
105
- if err != nil { return FileResult{}, routes, err }
105
+ if err != nil {
106
+ return FileResult{}, routes, err
107
+ }
106
108
  httpMethod, path, err := MethodAndPath(opts.Pattern)
107
109
  pathInfo, err := ParsedPath(path)
108
110
  if err != nil {
109
111
  return FileResult{}, routes, err
110
112
  }
111
113
  controllerMethod := method{
112
- Name: strcase.ToSnake(m.GetName()),
113
- RequestType: Classify(m.GetInputType()),
114
- Path: path,
115
- RestOptions: rubyRestOptions(restOpts),
116
- HttpMethod: httpMethod,
117
- Body: opts.Body,
118
- PathInfo: pathInfo,
114
+ Name: strcase.ToSnake(m.GetName()),
115
+ RequestType: Classify(m.GetInputType()),
116
+ Path: path,
117
+ RestOptions: rubyRestOptions(restOpts),
118
+ HttpMethod: httpMethod,
119
+ Body: opts.Body,
120
+ PathInfo: pathInfo,
119
121
  }
120
122
  data.Methods = append(data.Methods, controllerMethod)
121
123
  routes = append(routes, Route{
@@ -11,9 +11,10 @@ class MyServiceController < ActionController::Base
11
11
  rescue_from GRPC::BadStatus do |e|
12
12
  render json: GrpcRest.error_msg(e), status: GrpcRest.grpc_http_status(e.code)
13
13
  end
14
- rescue_from Google::Protobuf::TypeError do |e|
14
+ rescue_from ActionDispatch::Http::Parameters::ParseError, Google::Protobuf::TypeError do |e|
15
15
  render json: GrpcRest.error_msg(e), status: :bad_request
16
16
  end
17
+
17
18
  METHOD_PARAM_MAP = {
18
19
 
19
20
  "test" => [
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './spec_helper'
4
+ require 'src/proto/grpc/testing/test_services_pb'
5
+
6
+ RSpec.describe GrpcRest::BaseInterceptor, type: :class do
7
+ let(:rpc_service) { Grpc::Testing::TestService::Service.new }
8
+ let(:rpc_desc) { Grpc::Testing::TestService::Service.rpc_descs.values.first}
9
+ let(:message) { Grpc::Testing::SimpleRequest.new }
10
+
11
+ describe '#fail!' do
12
+ let(:error_message) { 'some message' }
13
+ let(:error_code) { :invalid_argument }
14
+
15
+ it 'intercepts and raises the error' do
16
+ request = Gruf::Controllers::Request.new(
17
+ method_key: :UnaryCall,
18
+ service: rpc_service,
19
+ rpc_desc: rpc_desc,
20
+ active_call: nil,
21
+ message: message)
22
+ interceptor = GrpcRest::BaseInterceptor.new(request, Gruf::Error.new)
23
+
24
+ expect{ interceptor.fail!(error_code, error_code, error_message) }.to raise_error(GRPC::InvalidArgument) do |error|
25
+ expect(error.message).to match(error_message)
26
+ expect(error.code).to eq(GRPC::Core::StatusCodes::INVALID_ARGUMENT)
27
+ end
28
+ end
29
+ end
30
+ end
data/spec/spec_helper.rb CHANGED
@@ -17,6 +17,7 @@ loader.inflector.inflect('protoc-gen-openapiv2' => 'ProtocGenOpenapiv2')
17
17
  loader.ignore("#{Rails.root}/spec/test_service_pb.rb")
18
18
  loader.setup
19
19
  require "#{Rails.root}/spec/test_service_pb.rb"
20
+ require "#{Rails.root}/lib/base_interceptor.rb"
20
21
 
21
22
  $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
22
23
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grpc-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.21
4
+ version: 0.1.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-12 00:00:00.000000000 Z
11
+ date: 2024-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grpc
@@ -81,6 +81,7 @@ files:
81
81
  - Gemfile.lock
82
82
  - README.md
83
83
  - grpc-rest.gemspec
84
+ - lib/base_interceptor.rb
84
85
  - lib/grpc_rest.rb
85
86
  - lib/grpc_rest/version.rb
86
87
  - protoc-gen-rails/.goreleaser.yml
@@ -101,6 +102,7 @@ files:
101
102
  - protoc-gen-rails/testdata/no_service/.keep
102
103
  - protoc-gen-rails/testdata/test.proto
103
104
  - protoc-gen-rails/testdata/test_service.proto
105
+ - spec/base_interceptor_spec.rb
104
106
  - spec/grpc_rest_spec.rb
105
107
  - spec/gruf_spec.rb
106
108
  - spec/protoc-gen-openapiv2/options/annotations_pb.rb
@@ -132,6 +134,7 @@ signing_key:
132
134
  specification_version: 4
133
135
  summary: Generate Rails controllers and routes from gRPC definitions.
134
136
  test_files:
137
+ - spec/base_interceptor_spec.rb
135
138
  - spec/grpc_rest_spec.rb
136
139
  - spec/gruf_spec.rb
137
140
  - spec/protoc-gen-openapiv2/options/annotations_pb.rb