twirp-on-rails 1.0.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97395472e03e70358a2a271d158f7661df878b3b9ada26d79b220975065d4b35
4
- data.tar.gz: b4188b09886154375a8f7e931d4d363c27bdf40a000044e73960e92266ccf2b1
3
+ metadata.gz: 308f1b4a611dd3496ffa026dae81410bffedffb0a2330ef009c4090b2ce71c24
4
+ data.tar.gz: dcfba3e14253882f6b7ba0943a89876789fb0d8e68015e397c6143e5417f7d35
5
5
  SHA512:
6
- metadata.gz: '0729dc21f25c3c40eda3fb080a70a67c67d3864a3be85a740e27b9e41e2d9d8548ccec114ebe42b923f240a33234090111ea00ce00dfa8729ecf43c546707002'
7
- data.tar.gz: 2d4d1bc20c93b7860356d431520ef7e5468ab3b1c45134ea63100bee64bf204517aefa768940c1429f105baadb8bf23eaa616e5e0d6b37cda8d8f1cf8cbdcd49
6
+ metadata.gz: 140d92258a215e8de86f641a39aeb7cf6e07034ee3c15e9ae187ed9a8f7d1d45d360a7240ecdc0599069dbe63558de7f2ba9ce15ecf7d7c538968bd96f784596
7
+ data.tar.gz: 3dcfdf03ddab84f16a8b8a052439b22e982456a7076c2ac54d2580244c16846b17cf70709a72bfa4a0be42743f139624bf338a97ff454d9fba83455be77eef90
data/.standard.yml CHANGED
@@ -2,3 +2,6 @@ ruby_version: 2.7
2
2
  plugins:
3
3
  - standard-performance
4
4
  - standard-rails
5
+ ignore:
6
+ - '**/*_pb.rb'
7
+ - '**/*_twirp.rb'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+
4
+ ## [1.2.0] - 2024-10-04
5
+
6
+ - Support rescue_from in handlers.
7
+
8
+ ## [1.1.0] - 2024-09-12
9
+
10
+ - Respect package namespace when looking for handlers.
11
+
3
12
  ## [0.1.0] - 2022-12-23
4
13
 
5
14
  - Initial release
data/Gemfile CHANGED
@@ -10,6 +10,6 @@ gem "rake"
10
10
  gem "debug"
11
11
  gem "rspec-rails"
12
12
  gem "sqlite3", "~> 1.4"
13
- gem "standard"
13
+ gem "standard", ">= 1.35.1"
14
14
  gem "standard-performance"
15
15
  gem "standard-rails"
data/README.md CHANGED
@@ -86,12 +86,47 @@ end
86
86
 
87
87
  Each handler method should return the appropriate Protobuf, or a `Twirp::Error`.
88
88
 
89
- TODO: Give more examples of both
89
+ #### Packages and Namespacing
90
+
91
+ Handlers can live in directories that reflect the service's package. For example, `haberdasher.proto` defines:
92
+
93
+ ```protobuf
94
+ package twirp.example.haberdasher;
95
+ ```
96
+
97
+ You can use the full path, or because many projects have only one namespace, we also let you skip the namespace for simplicity:
98
+
99
+ We look for the handler in either location:
100
+
101
+ `app/handlers/twirp/example/haberdasher/haberdasher_service_handler.rb` defines `Twirp::Example::Haberdasher::HaberdasherServiceHandler`
102
+
103
+ or
104
+
105
+ `app/handlers/haberdasher_service_handler.rb` defines `HaberdasherServiceHandler`
106
+
107
+
108
+ TODO: Give more examples of handlers
90
109
 
91
110
  ### Familiar Callbacks
92
111
 
93
112
  Use `before_action`, `around_action`, and other callbacks you're used to, as we build on [AbstractController::Callbacks](https://api.rubyonrails.org/classes/AbstractController/Callbacks.html).
94
113
 
114
+ ### rescue_from
115
+
116
+ Use `rescue_from` just like you would in a controller:
117
+
118
+ ```ruby
119
+ class HaberdasherServiceHandler < Twirp::Rails::Handler
120
+ rescue_from "ArgumentError" do |error|
121
+ Twirp::Error.invalid_argument(error.message)
122
+ end
123
+
124
+ rescue_from "Pundit::NotAuthorizedError", :not_authorized
125
+
126
+ ...
127
+ end
128
+ ```
129
+
95
130
  ### DRY Service Hooks
96
131
 
97
132
  Apply [Service Hooks](https://github.com/twitchtv/twirp-ruby/wiki/Service-Hooks) one time across multiple services.
@@ -4,7 +4,13 @@ module Twirp
4
4
  module Rails
5
5
  class Dispatcher
6
6
  def initialize(service_class)
7
- @service_handler = "#{service_class.service_name}Handler".constantize
7
+ # Check for a handler in the service's namespace, or in the root namespace
8
+ # e.g. Twirp::Example::Cobbler::CobblerHandler or ::CobblerHandler
9
+ @service_handler = if Object.const_defined?("#{service_class.module_parent}::#{service_class.service_name}Handler")
10
+ "#{service_class.module_parent}::#{service_class.service_name}Handler".constantize
11
+ else
12
+ "#{service_class.service_name}Handler".constantize
13
+ end
8
14
  end
9
15
 
10
16
  def respond_to_missing?(method, *)
@@ -4,6 +4,8 @@ module Twirp
4
4
  module Rails
5
5
  class Handler
6
6
  include Twirp::Rails::Callbacks
7
+ include ActiveSupport::Rescuable
8
+ using Twirp::Rails::Rescuable
7
9
 
8
10
  attr_reader :request, :env
9
11
  attr_reader :action_name
@@ -34,7 +36,11 @@ module Twirp
34
36
  ActiveSupport::Notifications.instrument("handler_run_callbacks.twirp_rails", handler: self.class.name, action: action_name, env: @env, request: @request) do
35
37
  run_callbacks(:process_action) do
36
38
  ActiveSupport::Notifications.instrument("handler_run.twirp_rails", handler: self.class.name, action: action_name, env: @env, request: @request) do |payload|
37
- payload[:response] = send_action(name)
39
+ payload[:response] = begin
40
+ send_action(name)
41
+ rescue => exception
42
+ rescue_with_handler_and_return(exception) || raise
43
+ end
38
44
  end
39
45
  end
40
46
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Twirp
4
+ module Rails
5
+ module Rescuable
6
+ refine ::ActiveSupport::Rescuable::ClassMethods do
7
+ # A slightly altered version of ActiveSupport::Rescuable#rescue_with_handler
8
+ # that returns the result rather than the handled exception
9
+ def rescue_with_handler_and_return(exception, object: self, visited_exceptions: [])
10
+ visited_exceptions << exception
11
+
12
+ if (handler = handler_for_rescue(exception, object: object))
13
+ handler.call exception
14
+ elsif exception
15
+ if visited_exceptions.include?(exception.cause)
16
+ nil
17
+ else
18
+ rescue_with_handler(exception.cause, object: object, visited_exceptions: visited_exceptions)
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ refine ::ActiveSupport::Rescuable do
25
+ def rescue_with_handler_and_return(exception)
26
+ self.class.rescue_with_handler_and_return exception, object: self
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Twirp
4
4
  module Rails
5
- VERSION = "1.0.1"
5
+ VERSION = "1.2.0"
6
6
  end
7
7
  end
data/lib/twirp/rails.rb CHANGED
@@ -15,6 +15,7 @@ require_relative "rails/callbacks"
15
15
  require_relative "rails/configuration"
16
16
  require_relative "rails/dispatcher"
17
17
  require_relative "rails/engine"
18
+ require_relative "rails/rescuable"
18
19
  require_relative "rails/handler"
19
20
 
20
21
  module Twirp
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twirp-on-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Morrison
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-05-20 00:00:00.000000000 Z
12
+ date: 2024-10-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -63,6 +63,7 @@ files:
63
63
  - lib/twirp/rails/engine.rb
64
64
  - lib/twirp/rails/handler.rb
65
65
  - lib/twirp/rails/rack/conditional_post.rb
66
+ - lib/twirp/rails/rescuable.rb
66
67
  - lib/twirp/rails/version.rb
67
68
  - sig/twirp/rails.rbs
68
69
  - twirp-rails.gemspec
@@ -88,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
89
  - !ruby/object:Gem::Version
89
90
  version: '0'
90
91
  requirements: []
91
- rubygems_version: 3.5.9
92
+ rubygems_version: 3.5.16
92
93
  signing_key:
93
94
  specification_version: 4
94
95
  summary: Use Twirp RPC with Rails