twirp-on-rails 1.0.1 → 1.2.0

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: 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