twirp 1.2.0 → 1.4.1
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 +5 -5
- data/README.md +5 -3
- data/lib/twirp/error.rb +5 -4
- data/lib/twirp/service.rb +15 -15
- data/lib/twirp/version.rb +1 -1
- data/test/error_test.rb +8 -8
- data/test/service_test.rb +9 -0
- data/twirp.gemspec +1 -0
- metadata +25 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 764fa4b20e00cd8c88643863bdcbc7d51d35bc17e60aa53ab86c8eb35e61a761
|
4
|
+
data.tar.gz: 1a8c622d398aff28244a6a9c3bec6a6a74d22a8f5cf6c71e65273e06021c501b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 521bdc421efb85856bfcab5ea2c9446d21072296cba21b007ec4f9015ec345ce14a166db5c8e078c8f754d61aaa9d19d039c96ab2b2a0d291c5768a4ef7dd5e8
|
7
|
+
data.tar.gz: db8f9343a888c4385cd4452a61020afc85664041f4e4b676e4b89220043ef03b2daddf8558435e71406c53d43f2ba38f9e0f40c1777c20e0d1ea73b47ad983b7
|
data/README.md
CHANGED
@@ -2,19 +2,21 @@
|
|
2
2
|
|
3
3
|
[Twirp is a protocol](https://twitchtv.github.io/twirp/docs/spec_v5.html) for routing and serialization of services defined in a [.proto file](https://developers.google.com/protocol-buffers/docs/proto3), allowing easy implementation of RPC services with auto-generated clients in different languages.
|
4
4
|
|
5
|
-
The [canonical implementation](https://github.com/twitchtv/twirp) is in Golang. The Twirp-Ruby project
|
5
|
+
The [canonical implementation](https://github.com/twitchtv/twirp) is in Golang. The Twirp-Ruby project is the official implementation in Ruby for both server and clients.
|
6
6
|
|
7
7
|
|
8
8
|
## Install
|
9
9
|
|
10
10
|
Add `gem "twirp"` to your Gemfile, or install with `gem install twirp`.
|
11
11
|
|
12
|
+
To auto-generate Ruby code from a proto file, use the `protoc` plugin and the `--ruby_out` option ([see Wiki page](https://github.com/twitchtv/twirp-ruby/wiki/Code-Generation)).
|
13
|
+
|
12
14
|
|
13
15
|
## Documentation
|
14
16
|
|
15
|
-
[
|
17
|
+
[On the wiki](https://github.com/twitchtv/twirp-ruby/wiki).
|
16
18
|
|
17
19
|
|
18
20
|
## Contributing
|
19
21
|
|
20
|
-
[
|
22
|
+
[On the CONTRIBUTING file](CONTRIBUTING.md).
|
data/lib/twirp/error.rb
CHANGED
@@ -49,10 +49,10 @@ module Twirp
|
|
49
49
|
ERROR_CODES_TO_HTTP_STATUS.key? code # one of the valid symbols
|
50
50
|
end
|
51
51
|
|
52
|
-
#
|
52
|
+
# Code constructors to ensure valid error codes. Example:
|
53
53
|
# Twirp::Error.internal("boom")
|
54
|
-
# Twirp::Error.invalid_argument("foo is mandatory",
|
55
|
-
# Twirp::Error.permission_denied("
|
54
|
+
# Twirp::Error.invalid_argument("foo is mandatory", mymeta: "foobar")
|
55
|
+
# Twirp::Error.permission_denied("Thou shall not pass!", target: "Balrog")
|
56
56
|
ERROR_CODES.each do |code|
|
57
57
|
define_singleton_method code do |msg, meta=nil|
|
58
58
|
new(code, msg, meta)
|
@@ -62,7 +62,7 @@ module Twirp
|
|
62
62
|
# Wrap another error as a Twirp::Error :internal.
|
63
63
|
def self.internal_with(err)
|
64
64
|
twerr = internal err.message, cause: err.class.name
|
65
|
-
twerr.cause = err
|
65
|
+
twerr.cause = err # availabe in error hook for inspection, but not in the response
|
66
66
|
twerr
|
67
67
|
end
|
68
68
|
|
@@ -80,6 +80,7 @@ module Twirp
|
|
80
80
|
@meta = validate_meta(meta)
|
81
81
|
end
|
82
82
|
|
83
|
+
# Key-value representation of the error. Can be directly serialized into JSON.
|
83
84
|
def to_h
|
84
85
|
h = {
|
85
86
|
code: @code,
|
data/lib/twirp/service.rb
CHANGED
@@ -23,10 +23,19 @@ module Twirp
|
|
23
23
|
extend ServiceDSL
|
24
24
|
|
25
25
|
class << self
|
26
|
-
|
26
|
+
|
27
|
+
# Whether to raise exceptions instead of handling them with exception_raised hooks.
|
27
28
|
# Useful during tests to easily debug and catch unexpected exceptions.
|
28
|
-
# Default false
|
29
|
-
|
29
|
+
attr_accessor :raise_exceptions # Default: false
|
30
|
+
|
31
|
+
# Rack response with a Twirp::Error
|
32
|
+
def error_response(twerr)
|
33
|
+
status = Twirp::ERROR_CODES_TO_HTTP_STATUS[twerr.code]
|
34
|
+
headers = {'Content-Type' => Encoding::JSON} # Twirp errors are always JSON, even if the request was protobuf
|
35
|
+
resp_body = Encoding.encode_json(twerr.to_h)
|
36
|
+
[status, headers, [resp_body]]
|
37
|
+
end
|
38
|
+
|
30
39
|
end
|
31
40
|
|
32
41
|
def initialize(handler)
|
@@ -181,11 +190,7 @@ module Twirp
|
|
181
190
|
def error_response(twerr, env)
|
182
191
|
begin
|
183
192
|
@on_error.each{|hook| hook.call(twerr, env) }
|
184
|
-
|
185
|
-
status = Twirp::ERROR_CODES_TO_HTTP_STATUS[twerr.code]
|
186
|
-
resp_body = Encoding.encode_json(twerr.to_h)
|
187
|
-
[status, error_response_headers, [resp_body]]
|
188
|
-
|
193
|
+
self.class.error_response(twerr)
|
189
194
|
rescue => e
|
190
195
|
return exception_response(e, env)
|
191
196
|
end
|
@@ -193,6 +198,7 @@ module Twirp
|
|
193
198
|
|
194
199
|
def exception_response(e, env)
|
195
200
|
raise e if self.class.raise_exceptions
|
201
|
+
|
196
202
|
begin
|
197
203
|
@exception_raised.each{|hook| hook.call(e, env) }
|
198
204
|
rescue => hook_e
|
@@ -200,13 +206,7 @@ module Twirp
|
|
200
206
|
end
|
201
207
|
|
202
208
|
twerr = Twirp::Error.internal_with(e)
|
203
|
-
|
204
|
-
[500, error_response_headers, [resp_body]]
|
205
|
-
end
|
206
|
-
|
207
|
-
def error_response_headers
|
208
|
-
# Twirp errors are always JSON, even if the request was protobuf
|
209
|
-
{'Content-Type' => Encoding::JSON}
|
209
|
+
self.class.error_response(twerr)
|
210
210
|
end
|
211
211
|
|
212
212
|
end
|
data/lib/twirp/version.rb
CHANGED
data/test/error_test.rb
CHANGED
@@ -3,7 +3,7 @@ require 'minitest/autorun'
|
|
3
3
|
require_relative '../lib/twirp/error'
|
4
4
|
|
5
5
|
class TestErrorCodes < Minitest::Test
|
6
|
-
|
6
|
+
|
7
7
|
def test_error_codes
|
8
8
|
assert_equal 17, Twirp::ERROR_CODES.size
|
9
9
|
|
@@ -13,7 +13,7 @@ class TestErrorCodes < Minitest::Test
|
|
13
13
|
end
|
14
14
|
|
15
15
|
# check some codes
|
16
|
-
assert_includes Twirp::ERROR_CODES, :internal
|
16
|
+
assert_includes Twirp::ERROR_CODES, :internal
|
17
17
|
assert_includes Twirp::ERROR_CODES, :not_found
|
18
18
|
assert_includes Twirp::ERROR_CODES, :invalid_argument
|
19
19
|
end
|
@@ -52,7 +52,7 @@ class TestTwirpError < Minitest::Test
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def test_invalid_constructor # Make sure that only supported codes are implemented (prevent bad metaprogramming)
|
55
|
-
assert_raises NoMethodError do
|
55
|
+
assert_raises NoMethodError do
|
56
56
|
Twirp::invalid_code_error "should fail"
|
57
57
|
end
|
58
58
|
end
|
@@ -67,7 +67,7 @@ class TestTwirpError < Minitest::Test
|
|
67
67
|
def test_new_with_valid_metadata
|
68
68
|
err = Twirp::Error.new(:internal, "woops", "meta" => "data", "for this" => "error")
|
69
69
|
assert_equal "data", err.meta["meta"]
|
70
|
-
assert_equal "error", err.meta["for this"]
|
70
|
+
assert_equal "error", err.meta["for this"]
|
71
71
|
assert_nil err.meta["something else"]
|
72
72
|
|
73
73
|
err = Twirp::Error.new(:internal, "woops", meta: "data")
|
@@ -78,11 +78,11 @@ class TestTwirpError < Minitest::Test
|
|
78
78
|
def test_invalid_metadata
|
79
79
|
Twirp::Error.new(:internal, "woops") # ensure the base case doesn't error
|
80
80
|
|
81
|
-
assert_raises ArgumentError do
|
81
|
+
assert_raises ArgumentError do
|
82
82
|
Twirp::Error.new(:internal, "woops", "string key" => :non_string_value)
|
83
83
|
end
|
84
84
|
|
85
|
-
assert_raises ArgumentError do
|
85
|
+
assert_raises ArgumentError do
|
86
86
|
Twirp::Error.new(:internal, "woops", "valid key" => "valid val", "bad_one" => 666)
|
87
87
|
end
|
88
88
|
end
|
@@ -91,8 +91,8 @@ class TestTwirpError < Minitest::Test
|
|
91
91
|
# returns a hash with attributes
|
92
92
|
err = Twirp::Error.new(:internal, "err msg", "key" => "val")
|
93
93
|
assert_equal({code: :internal, msg: "err msg", meta: {"key" => "val"}}, err.to_h)
|
94
|
-
|
95
|
-
# skips meta if not included
|
94
|
+
|
95
|
+
# skips meta if not included
|
96
96
|
err = Twirp::Error.new(:internal, "err msg")
|
97
97
|
assert_equal({code: :internal, msg: "err msg"}, err.to_h)
|
98
98
|
end
|
data/test/service_test.rb
CHANGED
@@ -12,6 +12,15 @@ class ServiceTest < Minitest::Test
|
|
12
12
|
Example::Haberdasher.raise_exceptions = true # configure for testing to make debugging easier
|
13
13
|
end
|
14
14
|
|
15
|
+
# Class method to make a Rack response with a Twirp errpr
|
16
|
+
def test_service_error_response
|
17
|
+
twerr = Twirp::Error.invalid_argument('foo')
|
18
|
+
resp = Twirp::Service.error_response(twerr)
|
19
|
+
assert_equal 400, resp[0]
|
20
|
+
assert_equal 'application/json', resp[1]['Content-Type']
|
21
|
+
assert_equal '{"code":"invalid_argument","msg":"foo"}', resp[2][0]
|
22
|
+
end
|
23
|
+
|
15
24
|
# The rpc DSL should properly build the base Twirp environment for each rpc method.
|
16
25
|
def test_rpcs_accessor
|
17
26
|
assert_equal 1, Example::Haberdasher.rpcs.size
|
data/twirp.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twirp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyrus A. Forbes
|
@@ -9,28 +9,28 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-12-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: google-protobuf
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "~>"
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '3.0'
|
21
18
|
- - ">="
|
22
19
|
- !ruby/object:Gem::Version
|
23
20
|
version: 3.0.0
|
21
|
+
- - "~>"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '3.0'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
|
-
- - "~>"
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: '3.0'
|
31
28
|
- - ">="
|
32
29
|
- !ruby/object:Gem::Version
|
33
30
|
version: 3.0.0
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: faraday
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,6 +87,20 @@ dependencies:
|
|
87
87
|
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: rack
|
92
|
+
requirement: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 2.0.8
|
97
|
+
type: :development
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 2.0.8
|
90
104
|
description: Twirp is a simple RPC framework with protobuf service definitions. The
|
91
105
|
Twirp gem provides native support for Ruby.
|
92
106
|
email:
|
@@ -134,15 +148,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
148
|
- !ruby/object:Gem::Version
|
135
149
|
version: '0'
|
136
150
|
requirements: []
|
137
|
-
|
138
|
-
rubygems_version: 2.6.8
|
151
|
+
rubygems_version: 3.0.3
|
139
152
|
signing_key:
|
140
153
|
specification_version: 4
|
141
154
|
summary: Twirp services in Ruby.
|
142
155
|
test_files:
|
143
|
-
- test/client_json_test.rb
|
144
156
|
- test/client_test.rb
|
145
157
|
- test/error_test.rb
|
146
|
-
- test/fake_services.rb
|
147
158
|
- test/license_header_test.rb
|
159
|
+
- test/fake_services.rb
|
148
160
|
- test/service_test.rb
|
161
|
+
- test/client_json_test.rb
|