action_controller-twirp 0.1.1 → 0.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 +4 -4
- data/README.md +42 -7
- data/lib/action_controller/twirp/config.rb +35 -0
- data/lib/action_controller/twirp/railtie.rb +0 -9
- data/lib/action_controller/twirp/version.rb +1 -1
- data/lib/action_controller/twirp.rb +33 -2
- data/lib/generators/action_controller/twirp/install_generator.rb +16 -0
- data/lib/generators/templates/action_controller_twirp.rb +30 -0
- metadata +5 -3
- data/lib/action_controller/twirp/twirp_error_renderer.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba5d8f3dbfc7dc8099def1e420b3a6c79cc2611df1295fad0c9e5f03ed3b1339
|
4
|
+
data.tar.gz: f2597df16242abd93b1ff1878b664db3f9e66cf63904e2030a47e000c32ba160
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec99d0597b6d950cbf5f65c6900ef64ac855871520bb682d7f916a70aa1dcb6892152a190f487ab639098f4ba44757db9387a420ef22e603326ec08468964d3c
|
7
|
+
data.tar.gz: 780bf0fab5393d22940621111dfdf811c78007369c64b9a18cfa1f8e50b0adddf3300e07ef6a592605a936d987c481e73835e115109fccaa2a60e3b8ad6902d4
|
data/README.md
CHANGED
@@ -51,13 +51,6 @@ Finally, implement rpc method your controller
|
|
51
51
|
class UsersController < ApplicationController # :nodoc:
|
52
52
|
include ActionController::Twirp
|
53
53
|
|
54
|
-
rescue_from ActiveRecord::RecordNotFound do |e|
|
55
|
-
twerr = Twirp::Error.not_found('The message',
|
56
|
-
reason: e.class.name.demodulize,
|
57
|
-
id: params[:id].to_s)
|
58
|
-
render twirp_error: twerr
|
59
|
-
end
|
60
|
-
|
61
54
|
USERS = [
|
62
55
|
{ id: 1, name: 'Anna' },
|
63
56
|
{ id: 2, name: 'Reina' }
|
@@ -77,6 +70,48 @@ class UsersController < ApplicationController # :nodoc:
|
|
77
70
|
end
|
78
71
|
```
|
79
72
|
|
73
|
+
### Error handling
|
74
|
+
|
75
|
+
twirp-ruby eventually provides us with a rack app, which handles the exception and returns a response when an exception occurs.
|
76
|
+
Provide settings for exception handling, as the status code or body may be unexpected when an error occurs.
|
77
|
+
|
78
|
+
You can install initializer by rails generate command
|
79
|
+
```sh
|
80
|
+
> bin/rails generate action_controller:twirp:install
|
81
|
+
|
82
|
+
> cat config/initializers/action_controller_twirp.rb
|
83
|
+
# frozen_string_literal: true
|
84
|
+
|
85
|
+
ActionController::Twirp::Config.setup do |config|
|
86
|
+
# Handle exceptions
|
87
|
+
# true: handling by ActionController::Twirp
|
88
|
+
# false: handling by Twirp::Service (default)
|
89
|
+
# config.handle_exceptions = false
|
90
|
+
|
91
|
+
# ---
|
92
|
+
# The following configurations ignore when handle_exceptions is false
|
93
|
+
# ---
|
94
|
+
|
95
|
+
# Mapping your exception classes and Twirp::Error::ERROR_CODES
|
96
|
+
# String => Symbol
|
97
|
+
# config.exception_codes = {
|
98
|
+
# 'ActiveRecord::RecordInvalid' => :invalid_argument,
|
99
|
+
# 'ActiveRecord::RecordNotFound' => :not_found,
|
100
|
+
# 'My::Exception' => :aborted,
|
101
|
+
# }
|
102
|
+
|
103
|
+
# Block to make Twirp::Error message when exception_codes exist
|
104
|
+
# config.build_message = ->(exception) {}
|
105
|
+
|
106
|
+
# Block to make Twirp::Error metadata. when exception_codes exist
|
107
|
+
# It MUST return Hash value
|
108
|
+
# config.build_metadata = ->(exception) {}
|
109
|
+
|
110
|
+
# Block to run additional process. e.g. logging
|
111
|
+
# config.on_exceptions = ->(exception) {}
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
80
115
|
## Contributing
|
81
116
|
Contribution directions go here.
|
82
117
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
4
|
+
|
5
|
+
module ActionController
|
6
|
+
module Twirp
|
7
|
+
# Configration for ActionController::Twirp
|
8
|
+
module Config
|
9
|
+
# Handle exceptions
|
10
|
+
# true: handling by ActionController::Twirp
|
11
|
+
# false: handling by Twirp::Service
|
12
|
+
mattr_accessor :handle_exceptions, default: false
|
13
|
+
|
14
|
+
# ---
|
15
|
+
# The following configurations ignore when handle_exceptions is false
|
16
|
+
# ---
|
17
|
+
|
18
|
+
# Mapping your exception classes and Twirp::Error::ERROR_CODES
|
19
|
+
mattr_accessor :exception_codes, default: {}
|
20
|
+
|
21
|
+
# Block to make Twirp::Error message
|
22
|
+
mattr_accessor :build_message, default: ->(exception) {}
|
23
|
+
|
24
|
+
# Block to make Twirp::Error metadata
|
25
|
+
mattr_accessor :build_metadata, default: ->(exception) {}
|
26
|
+
|
27
|
+
# Block to run additional process. e.g. logging
|
28
|
+
mattr_accessor :on_exceptions, default: ->(exception) {}
|
29
|
+
|
30
|
+
def self.setup
|
31
|
+
yield self
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,19 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'action_controller/twirp/twirp_error_renderer'
|
4
3
|
require 'action_dispatch/twirp/railtie'
|
5
4
|
|
6
5
|
module ActionController
|
7
6
|
module Twirp
|
8
7
|
class Railtie < ::Rails::Railtie # :nodoc:
|
9
|
-
initializer 'action_controller.twirp' do
|
10
|
-
ActiveSupport.on_load(:action_controller) do
|
11
|
-
ActionController::Renderers.add :twirp_error do |content, options|
|
12
|
-
renderer = TwirpErrorRenderer.new(content, options)
|
13
|
-
render(**renderer.to_render_option)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
8
|
end
|
18
9
|
end
|
19
10
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'action_controller/twirp/version'
|
4
4
|
require 'action_controller/twirp/railtie'
|
5
|
+
require 'action_controller/twirp/config'
|
5
6
|
|
6
7
|
module ActionController
|
7
8
|
# Module to execute your implemented methods on Twirp with Rails
|
@@ -10,9 +11,9 @@ module ActionController
|
|
10
11
|
|
11
12
|
# Override it to call a twirp class from request path
|
12
13
|
def send_action(*_args)
|
13
|
-
twirp_service_class.raise_exceptions =
|
14
|
+
twirp_service_class.raise_exceptions = Config.handle_exceptions
|
14
15
|
|
15
|
-
status, header, body =
|
16
|
+
status, header, body = twirp_action
|
16
17
|
|
17
18
|
response.status = status
|
18
19
|
response.header.merge!(header)
|
@@ -25,5 +26,35 @@ module ActionController
|
|
25
26
|
class_name = request.path.split('/')[-2].underscore.gsub('.', '/').classify
|
26
27
|
@twirp_service_class = "#{class_name}Service".constantize
|
27
28
|
end
|
29
|
+
|
30
|
+
def twirp_action
|
31
|
+
twirp_service_class.new(self)&.call(request.env)
|
32
|
+
rescue StandardError => e
|
33
|
+
begin
|
34
|
+
Config.on_exceptions.call(e)
|
35
|
+
rescue StandardError => hook_e
|
36
|
+
e = hook_e
|
37
|
+
end
|
38
|
+
twirp_error_response(e)
|
39
|
+
end
|
40
|
+
|
41
|
+
def twirp_error_response(exception)
|
42
|
+
twerr = twirp_error(exception)
|
43
|
+
twirp_service_class.error_response(twerr)
|
44
|
+
end
|
45
|
+
|
46
|
+
def twirp_error(exception)
|
47
|
+
if Config.exception_codes.key?(exception.class.to_s)
|
48
|
+
code = Config.exception_codes[exception.class.to_s]
|
49
|
+
message = Config.build_message.call(exception)
|
50
|
+
metadata = Config.build_metadata.call(exception)
|
51
|
+
|
52
|
+
::Twirp::Error.public_send(code, message, metadata)
|
53
|
+
else
|
54
|
+
::Twirp::Error.internal_with(exception)
|
55
|
+
end
|
56
|
+
rescue StandardError => e
|
57
|
+
::Twirp::Error.internal_with(e)
|
58
|
+
end
|
28
59
|
end
|
29
60
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module Twirp
|
5
|
+
module Generators
|
6
|
+
class InstallGenerator < Rails::Generators::Base # :nodoc:
|
7
|
+
source_root File.expand_path('../../templates', __dir__)
|
8
|
+
|
9
|
+
desc 'Creates a ActionController::Twirp initializer'
|
10
|
+
def copy_initializer
|
11
|
+
template 'action_controller_twirp.rb', 'config/initializers/action_controller_twirp.rb'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ActionController::Twirp::Config.setup do |config|
|
4
|
+
# Handle exceptions
|
5
|
+
# true: handling by ActionTwirpRails
|
6
|
+
# false: handling by Twirp::Service (default)
|
7
|
+
# config.handle_exceptions = false
|
8
|
+
|
9
|
+
# ---
|
10
|
+
# The following configurations ignore when handle_exceptions is false
|
11
|
+
# ---
|
12
|
+
|
13
|
+
# Mapping your exception classes and Twirp::Error::ERROR_CODES
|
14
|
+
# String => Symbol
|
15
|
+
# config.exception_codes = {
|
16
|
+
# 'ActiveRecord::RecordInvalid' => :invalid_argument,
|
17
|
+
# 'ActiveRecord::RecordNotFound' => :not_found,
|
18
|
+
# 'My::Exception' => :aborted,
|
19
|
+
# }
|
20
|
+
|
21
|
+
# Block to make Twirp::Error message when exception_codes exist
|
22
|
+
# config.build_message = ->(exception) {}
|
23
|
+
|
24
|
+
# Block to make Twirp::Error metadata. when exception_codes exist
|
25
|
+
# It MUST return Hash value
|
26
|
+
# config.build_metadata = ->(exception) {}
|
27
|
+
|
28
|
+
# Block to run additional process. e.g. logging
|
29
|
+
# config.on_exceptions = ->(exception) {}
|
30
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action_controller-twirp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kosuke Arisawa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -63,11 +63,13 @@ files:
|
|
63
63
|
- README.md
|
64
64
|
- Rakefile
|
65
65
|
- lib/action_controller/twirp.rb
|
66
|
+
- lib/action_controller/twirp/config.rb
|
66
67
|
- lib/action_controller/twirp/railtie.rb
|
67
|
-
- lib/action_controller/twirp/twirp_error_renderer.rb
|
68
68
|
- lib/action_controller/twirp/version.rb
|
69
69
|
- lib/action_dispatch/routing/mapper/twirp.rb
|
70
70
|
- lib/action_dispatch/twirp/railtie.rb
|
71
|
+
- lib/generators/action_controller/twirp/install_generator.rb
|
72
|
+
- lib/generators/templates/action_controller_twirp.rb
|
71
73
|
- lib/tasks/action_controller/twirp_tasks.rake
|
72
74
|
homepage: https://github.com/arisawa/action_controller-twirp
|
73
75
|
licenses:
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActionController
|
4
|
-
module Twirp
|
5
|
-
# Convert Twirp::Error to #render option
|
6
|
-
class TwirpErrorRenderer
|
7
|
-
# @param content [Twirp::Error] given as a value of :twirp_error key of render method.
|
8
|
-
# @param options [Hash] options of render method.
|
9
|
-
def initialize(content, options)
|
10
|
-
unless content.is_a?(::Twirp::Error)
|
11
|
-
raise ArgumentError, 'Only Twirp::Error instance can be specified'
|
12
|
-
end
|
13
|
-
|
14
|
-
@content = content
|
15
|
-
@options = options.dup
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_render_option
|
19
|
-
{
|
20
|
-
json: twirp_error.to_h,
|
21
|
-
**@options.merge(status: status, content_type: content_type)
|
22
|
-
}
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def twirp_error
|
28
|
-
return @twirp_error if defined? @twirp_error
|
29
|
-
|
30
|
-
code = @content.code
|
31
|
-
|
32
|
-
@twirp_error = if ::Twirp::Error.valid_code?(code)
|
33
|
-
@content
|
34
|
-
else
|
35
|
-
::Twirp::Error.internal("Invalid code: #{code}", invalid_code: code.to_s)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def status
|
40
|
-
::Twirp::ERROR_CODES_TO_HTTP_STATUS[twirp_error.code]
|
41
|
-
end
|
42
|
-
|
43
|
-
def content_type
|
44
|
-
::Twirp::Encoding::JSON
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|