twirp 1.2.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|