x 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -28
  3. data/README.md +6 -2
  4. data/lib/x/authenticator.rb +8 -0
  5. data/lib/x/bearer_token_authenticator.rb +5 -3
  6. data/lib/x/cgi.rb +15 -0
  7. data/lib/x/client.rb +40 -40
  8. data/lib/x/connection.rb +39 -76
  9. data/lib/x/errors/bad_gateway.rb +5 -0
  10. data/lib/x/errors/{not_found_error.rb → bad_request.rb} +1 -1
  11. data/lib/x/errors/connection_exception.rb +5 -0
  12. data/lib/x/errors/error.rb +1 -6
  13. data/lib/x/errors/{forbidden_error.rb → forbidden.rb} +1 -1
  14. data/lib/x/errors/gateway_timeout.rb +5 -0
  15. data/lib/x/errors/{bad_request_error.rb → gone.rb} +1 -1
  16. data/lib/x/errors/network_error.rb +1 -1
  17. data/lib/x/errors/not_acceptable.rb +5 -0
  18. data/lib/x/errors/not_found.rb +5 -0
  19. data/lib/x/errors/payload_too_large.rb +5 -0
  20. data/lib/x/errors/service_unavailable.rb +5 -0
  21. data/lib/x/errors/too_many_redirects.rb +5 -0
  22. data/lib/x/errors/too_many_requests.rb +29 -0
  23. data/lib/x/errors/unauthorized.rb +5 -0
  24. data/lib/x/errors/unprocessable_entity.rb +5 -0
  25. data/lib/x/{media_upload.rb → media_uploader.rb} +12 -15
  26. data/lib/x/oauth_authenticator.rb +10 -15
  27. data/lib/x/redirect_handler.rb +26 -22
  28. data/lib/x/request_builder.rb +22 -35
  29. data/lib/x/response_parser.rb +92 -0
  30. data/lib/x/version.rb +1 -1
  31. data/sig/x.rbs +101 -87
  32. metadata +21 -13
  33. data/lib/x/errors/authentication_error.rb +0 -5
  34. data/lib/x/errors/payload_too_large_error.rb +0 -5
  35. data/lib/x/errors/service_unavailable_error.rb +0 -5
  36. data/lib/x/errors/too_many_redirects_error.rb +0 -5
  37. data/lib/x/errors/too_many_requests_error.rb +0 -29
  38. data/lib/x/response_handler.rb +0 -63
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a01e8a21951f3b998cfae0253c4d35c5412ac39f94681283b9059d4a196651e
4
- data.tar.gz: 5b4a5bb02d86b27391b005acb329893025222c20e9d0c99b88ed0d7e6322dc5e
3
+ metadata.gz: e5af820e6e3cd8b04becf201ad7af96c8d95d9206112673888f91c5ecf923187
4
+ data.tar.gz: 6f0f561be192153eca2cc7356c823c87bd98f0987256875892c0a2e9ea12b82d
5
5
  SHA512:
6
- metadata.gz: 8972eafdb4c041a61258f409fef5a93dc0ff56b70e5c8dd384e126652c1ab32a4e52dc56bd253d7c204ea6313e3ac321e93c7245c722c0d5491b59443c63435a
7
- data.tar.gz: 4a5dfb958b61b78cdcf9312250d3ba00182894241da1c3e9114f08f1029fb174be07043f607a864986e3d09d6d308dfac4d13549e2483d5746235b34c4dd05a2
6
+ metadata.gz: 8b208d5ba10604a34a57b0dd2ee5dc0992eb801cfbcc287a7f1b0d54444f214050a2c25b2ec6291868a8c35fff09260ad91a82641be830b87d3e6abf0207fc3e
7
+ data.tar.gz: 24c6a1083358b60065698320372d53404bab9c319aaad13b097508a7041653ac9d45aabd8e6f7a99204accddfc1beeeb2bce18bd67fa9ba816eb6282cbab4227
data/CHANGELOG.md CHANGED
@@ -1,69 +1,82 @@
1
+ ## [0.11.0] - 2023-10-24
2
+
3
+ * Add base Authenticator class (8c66ce2)
4
+ * Consistently use keyword arguments (3beb271)
5
+ * Use patern matching to build request (4d001c7)
6
+ * Rename ResponseHandler to ResponseParser (498e890)
7
+ * Rename methods to be more consistent (5b8c655)
8
+ * Rename MediaUpload to MediaUploader (84f0c15)
9
+ * Add mutant and kill mutants (b124968)
10
+ * Fix authentication bug with request URLs that contain spaces (8de3174)
11
+ * Refactor errors (853d39c)
12
+ * Make Connection class threadsafe (d95d285)
13
+
1
14
  ## [0.10.0] - 2023-10-08
2
15
 
3
- - Add media upload helper methods (6c6a267)
4
- - Add PayloadTooLargeError class (cd61850)
16
+ * Add media upload helper methods (6c6a267)
17
+ * Add PayloadTooLargeError class (cd61850)
5
18
 
6
19
  ## [0.9.1] - 2023-10-06
7
20
 
8
- - Allow successful empty responses (06bf7db)
9
- - Update default User-Agent string (296b36a)
10
- - Move query parameter escaping into RequestBuilder (56d6bd2)
21
+ * Allow successful empty responses (06bf7db)
22
+ * Update default User-Agent string (296b36a)
23
+ * Move query parameter escaping into RequestBuilder (56d6bd2)
11
24
 
12
25
  ## [0.9.0] - 2023-09-26
13
26
 
14
- - Add support for HTTP proxies (3740f4f)
27
+ * Add support for HTTP proxies (3740f4f)
15
28
 
16
29
  ## [0.8.1] - 2023-09-20
17
30
 
18
- - Fix bug where setting Connection#base_uri= doesn't update the HTTP client (d5a89db)
31
+ * Fix bug where setting Connection#base_uri= doesn't update the HTTP client (d5a89db)
19
32
 
20
33
  ## [0.8.0] - 2023-09-14
21
34
 
22
- - Add (back) bearer token authentication (62e141d)
23
- - Follow redirects (90a8c55)
24
- - Parse error responses with Content-Type: application/problem+json (0b697d9)
35
+ * Add (back) bearer token authentication (62e141d)
36
+ * Follow redirects (90a8c55)
37
+ * Parse error responses with Content-Type: application/problem+json (0b697d9)
25
38
 
26
39
  ## [0.7.1] - 2023-09-02
27
40
 
28
- - Fix bug in X::Authenticator#split_uri (ebc9d5f)
41
+ * Fix bug in X::Authenticator#split_uri (ebc9d5f)
29
42
 
30
43
  ## [0.7.0] - 2023-09-02
31
44
 
32
- - Remove OAuth gem (7c29bb1)
45
+ * Remove OAuth gem (7c29bb1)
33
46
 
34
47
  ## [0.6.0] - 2023-08-30
35
48
 
36
- - Add configurable debug output stream for logging (fd2d4b0)
37
- - Remove bearer token authentication (efff940)
38
- - Define RBS type signatures (d7f63ba)
49
+ * Add configurable debug output stream for logging (fd2d4b0)
50
+ * Remove bearer token authentication (efff940)
51
+ * Define RBS type signatures (d7f63ba)
39
52
 
40
53
  ## [0.5.1] - 2023-08-16
41
54
 
42
- - Fix bearer token authentication (1a1ca93)
55
+ * Fix bearer token authentication (1a1ca93)
43
56
 
44
57
  ## [0.5.0] - 2023-08-10
45
58
 
46
- - Add configurable write timeout (2a31f84)
47
- - Use built-in Gem::Version class (066e0b6)
59
+ * Add configurable write timeout (2a31f84)
60
+ * Use built-in Gem::Version class (066e0b6)
48
61
 
49
62
  ## [0.4.0] - 2023-08-06
50
63
 
51
- - Refactor Client into Authenticator, RequestBuilder, Connection, ResponseHandler (6bee1e9)
52
- - Add configurable open timeout (1000f9d)
53
- - Allow configuration of content type (f33a732)
64
+ * Refactor Client into Authenticator, RequestBuilder, Connection, ResponseHandler (6bee1e9)
65
+ * Add configurable open timeout (1000f9d)
66
+ * Allow configuration of content type (f33a732)
54
67
 
55
68
  ## [0.3.0] - 2023-08-04
56
69
 
57
- - Add accessors to X::Client (e61fa73)
58
- - Add configurable read timeout (41502b9)
59
- - Handle network-related errors (9ed1fb4)
60
- - Include response body in errors (a203e6a)
70
+ * Add accessors to X::Client (e61fa73)
71
+ * Add configurable read timeout (41502b9)
72
+ * Handle network-related errors (9ed1fb4)
73
+ * Include response body in errors (a203e6a)
61
74
 
62
75
  ## [0.2.0] - 2023-08-02
63
76
 
64
- - Allow configuration of base URL (4bc0531)
65
- - Improve error handling (14dc0cd)
77
+ * Allow configuration of base URL (4bc0531)
78
+ * Improve error handling (14dc0cd)
66
79
 
67
80
  ## [0.1.0] - 2023-08-02
68
81
 
69
- - Initial release
82
+ * Initial release
data/README.md CHANGED
@@ -130,11 +130,15 @@ Pull requests will only be accepted if they meet all the following criteria:
130
130
 
131
131
  bundle exec rake standard
132
132
 
133
- 2. For any new code paths, tests must be added to maintain 100% C0 code coverage. This can be verified with:
133
+ 2. 100% C0 code coverage. This can be verified with:
134
134
 
135
135
  bundle exec rake test
136
136
 
137
- 3. For any new classes or methods, RBS type signatures must be added (to sig/x.rbs). This can be verified with:
137
+ 3. 100% mutation coverage. This can be verified with:
138
+
139
+ bundle exec rake mutant
140
+
141
+ 4. RBS type signatures (in `sig/x.rbs`). This can be verified with:
138
142
 
139
143
  bundle exec rake steep
140
144
 
@@ -0,0 +1,8 @@
1
+ module X
2
+ # Base Authenticator class
3
+ class Authenticator
4
+ def header(_request)
5
+ {"Authorization" => ""}
6
+ end
7
+ end
8
+ end
@@ -1,14 +1,16 @@
1
+ require_relative "authenticator"
2
+
1
3
  module X
2
4
  # Handles bearer token authentication
3
- class BearerTokenAuthenticator
5
+ class BearerTokenAuthenticator < Authenticator
4
6
  attr_accessor :bearer_token
5
7
 
6
- def initialize(bearer_token)
8
+ def initialize(bearer_token:) # rubocop:disable Lint/MissingSuper
7
9
  @bearer_token = bearer_token
8
10
  end
9
11
 
10
12
  def header(_request)
11
- "Bearer #{bearer_token}"
13
+ {"Authorization" => "Bearer #{bearer_token}"}
12
14
  end
13
15
  end
14
16
  end
data/lib/x/cgi.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "cgi"
2
+
3
+ module X
4
+ # Namespaced CGI class
5
+ class CGI
6
+ # TODO: Replace CGI.escape with CGI.escapeURIComponent when support for Ruby 3.1 is dropped
7
+ def self.escape(value)
8
+ ::CGI.escape(value).gsub("+", "%20")
9
+ end
10
+
11
+ def self.escape_params(params)
12
+ params.map { |k, v| "#{k}=#{escape(v)}" }.join("&")
13
+ end
14
+ end
15
+ end
data/lib/x/client.rb CHANGED
@@ -1,87 +1,87 @@
1
1
  require "forwardable"
2
2
  require_relative "bearer_token_authenticator"
3
- require_relative "oauth_authenticator"
4
3
  require_relative "connection"
4
+ require_relative "oauth_authenticator"
5
5
  require_relative "redirect_handler"
6
6
  require_relative "request_builder"
7
- require_relative "response_handler"
7
+ require_relative "response_parser"
8
8
 
9
9
  module X
10
10
  # Main public interface
11
11
  class Client
12
12
  extend Forwardable
13
13
 
14
+ DEFAULT_BASE_URL = "https://api.twitter.com/2/".freeze
15
+
16
+ attr_accessor :base_url
17
+
14
18
  def_delegators :@authenticator, :bearer_token, :api_key, :api_key_secret, :access_token, :access_token_secret
15
19
  def_delegators :@authenticator, :bearer_token=, :api_key=, :api_key_secret=, :access_token=, :access_token_secret=
16
- def_delegators :@connection, :base_uri, :open_timeout, :read_timeout, :write_timeout, :debug_output
17
- def_delegators :@connection, :base_uri=, :open_timeout=, :read_timeout=, :write_timeout=, :debug_output=
18
- def_delegators :@request_builder, :content_type, :user_agent
19
- def_delegators :@request_builder, :content_type=, :user_agent=
20
- def_delegators :@response_handler, :array_class, :object_class
21
- def_delegators :@response_handler, :array_class=, :object_class=
22
- alias_method :base_url, :base_uri
23
- alias_method :base_url=, :base_uri=
24
- attr_accessor :authenticator, :connection, :request_builder, :redirect_handler, :response_handler
20
+ def_delegators :@connection, :open_timeout, :read_timeout, :write_timeout, :proxy_url, :debug_output
21
+ def_delegators :@connection, :open_timeout=, :read_timeout=, :write_timeout=, :proxy_url=, :debug_output=
22
+ def_delegators :@redirect_handler, :max_redirects
23
+ def_delegators :@redirect_handler, :max_redirects=
24
+ def_delegators :@response_parser, :array_class, :object_class
25
+ def_delegators :@response_parser, :array_class=, :object_class=
25
26
 
26
27
  def initialize(bearer_token: nil,
27
28
  api_key: nil, api_key_secret: nil, access_token: nil, access_token_secret: nil,
28
- base_url: Connection::DEFAULT_BASE_URL,
29
+ base_url: DEFAULT_BASE_URL,
29
30
  open_timeout: Connection::DEFAULT_OPEN_TIMEOUT,
30
31
  read_timeout: Connection::DEFAULT_READ_TIMEOUT,
31
32
  write_timeout: Connection::DEFAULT_WRITE_TIMEOUT,
32
33
  proxy_url: nil,
33
- content_type: RequestBuilder::DEFAULT_CONTENT_TYPE,
34
- user_agent: RequestBuilder::DEFAULT_USER_AGENT,
35
34
  debug_output: nil,
36
- array_class: ResponseHandler::DEFAULT_ARRAY_CLASS,
37
- object_class: ResponseHandler::DEFAULT_OBJECT_CLASS,
35
+ array_class: nil,
36
+ object_class: nil,
38
37
  max_redirects: RedirectHandler::DEFAULT_MAX_REDIRECTS)
39
38
 
39
+ @base_url = base_url
40
40
  initialize_authenticator(bearer_token, api_key, api_key_secret, access_token, access_token_secret)
41
- @connection = Connection.new(base_url: base_url, open_timeout: open_timeout, read_timeout: read_timeout,
41
+ @connection = Connection.new(open_timeout: open_timeout, read_timeout: read_timeout,
42
42
  write_timeout: write_timeout, debug_output: debug_output, proxy_url: proxy_url)
43
- @request_builder = RequestBuilder.new(content_type: content_type, user_agent: user_agent)
44
- @redirect_handler = RedirectHandler.new(@authenticator, @connection, @request_builder,
45
- max_redirects: max_redirects)
46
- @response_handler = ResponseHandler.new(array_class: array_class, object_class: object_class)
43
+ @request_builder = RequestBuilder.new
44
+ @redirect_handler = RedirectHandler.new(authenticator: @authenticator, connection: @connection,
45
+ request_builder: @request_builder, max_redirects: max_redirects)
46
+ @response_parser = ResponseParser.new(array_class: array_class, object_class: object_class)
47
47
  end
48
48
 
49
- def get(endpoint)
50
- send_request(:get, endpoint)
49
+ def get(endpoint, headers: {})
50
+ execute_request(:get, endpoint, headers: headers)
51
51
  end
52
52
 
53
- def post(endpoint, body = nil)
54
- send_request(:post, endpoint, body)
53
+ def post(endpoint, body = nil, headers: {})
54
+ execute_request(:post, endpoint, body: body, headers: headers)
55
55
  end
56
56
 
57
- def put(endpoint, body = nil)
58
- send_request(:put, endpoint, body)
57
+ def put(endpoint, body = nil, headers: {})
58
+ execute_request(:put, endpoint, body: body, headers: headers)
59
59
  end
60
60
 
61
- def delete(endpoint)
62
- send_request(:delete, endpoint)
61
+ def delete(endpoint, headers: {})
62
+ execute_request(:delete, endpoint, headers: headers)
63
63
  end
64
64
 
65
65
  private
66
66
 
67
67
  def initialize_authenticator(bearer_token, api_key, api_key_secret, access_token, access_token_secret)
68
68
  @authenticator = if bearer_token
69
- BearerTokenAuthenticator.new(bearer_token)
69
+ BearerTokenAuthenticator.new(bearer_token: bearer_token)
70
70
  elsif api_key && api_key_secret && access_token && access_token_secret
71
- OauthAuthenticator.new(api_key, api_key_secret, access_token, access_token_secret)
71
+ OAuthAuthenticator.new(api_key: api_key, api_key_secret: api_key_secret, access_token: access_token,
72
+ access_token_secret: access_token_secret)
72
73
  else
73
- raise ArgumentError,
74
- "Client must be initialized with either a bearer_token or " \
75
- "an api_key, api_key_secret, access_token, and access_token_secret"
74
+ Authenticator.new
76
75
  end
77
76
  end
78
77
 
79
- def send_request(http_method, endpoint, body = nil)
80
- uri = URI.join(base_uri.to_s, endpoint)
81
- request = @request_builder.build(@authenticator, http_method, uri, body: body)
82
- response = @connection.send_request(request)
83
- final_response = @redirect_handler.handle_redirects(response, request, base_uri)
84
- @response_handler.handle(final_response)
78
+ def execute_request(http_method, endpoint, headers:, body: nil)
79
+ uri = URI.join(base_url, endpoint)
80
+ request = @request_builder.build(authenticator: @authenticator, http_method: http_method, uri: uri, body: body,
81
+ headers: headers)
82
+ response = @connection.perform(request: request)
83
+ response = @redirect_handler.handle(response: response, request: request, base_url: base_url)
84
+ @response_parser.parse(response: response)
85
85
  end
86
86
  end
87
87
  end
data/lib/x/connection.rb CHANGED
@@ -9,12 +9,12 @@ module X
9
9
  class Connection
10
10
  extend Forwardable
11
11
 
12
- DEFAULT_BASE_URL = "https://api.twitter.com/2/".freeze
13
- DEFAULT_HOST = "https://api.twitter.com".freeze
12
+ DEFAULT_HOST = "api.twitter.com".freeze
14
13
  DEFAULT_PORT = 443
15
14
  DEFAULT_OPEN_TIMEOUT = 60 # seconds
16
15
  DEFAULT_READ_TIMEOUT = 60 # seconds
17
16
  DEFAULT_WRITE_TIMEOUT = 60 # seconds
17
+ DEFAULT_DEBUG_OUTPUT = File.open(File::NULL, "w")
18
18
  NETWORK_ERRORS = [
19
19
  Errno::ECONNREFUSED,
20
20
  Errno::ECONNRESET,
@@ -23,95 +23,58 @@ module X
23
23
  OpenSSL::SSL::SSLError
24
24
  ].freeze
25
25
 
26
- attr_reader :base_uri, :proxy_uri, :http_client
27
-
28
- def_delegators :@http_client, :open_timeout, :read_timeout, :write_timeout
29
- def_delegators :@http_client, :open_timeout=, :read_timeout=, :write_timeout=
30
- def_delegator :@http_client, :set_debug_output, :debug_output=
31
-
32
- def initialize(base_url: DEFAULT_BASE_URL, open_timeout: DEFAULT_OPEN_TIMEOUT,
33
- read_timeout: DEFAULT_READ_TIMEOUT, write_timeout: DEFAULT_WRITE_TIMEOUT, proxy_url: nil, debug_output: nil)
34
- @proxy_uri = URI(proxy_url) unless proxy_url.nil?
35
- self.base_uri = base_url
36
- apply_http_client_settings(
37
- open_timeout: open_timeout,
38
- read_timeout: read_timeout,
39
- write_timeout: write_timeout,
40
- debug_output: debug_output
41
- )
26
+ attr_accessor :open_timeout, :read_timeout, :write_timeout, :debug_output
27
+ attr_reader :proxy_url, :proxy_uri
28
+
29
+ def_delegator :proxy_uri, :host, :proxy_host
30
+ def_delegator :proxy_uri, :port, :proxy_port
31
+ def_delegator :proxy_uri, :user, :proxy_user
32
+ def_delegator :proxy_uri, :password, :proxy_pass
33
+
34
+ def initialize(open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT,
35
+ write_timeout: DEFAULT_WRITE_TIMEOUT, debug_output: DEFAULT_DEBUG_OUTPUT, proxy_url: nil)
36
+ @open_timeout = open_timeout
37
+ @read_timeout = read_timeout
38
+ @write_timeout = write_timeout
39
+ @debug_output = debug_output
40
+ self.proxy_url = proxy_url unless proxy_url.nil?
42
41
  end
43
42
 
44
- def send_request(request)
45
- response = @http_client.request(request)
43
+ def perform(request:)
44
+ host = request.uri.host || DEFAULT_HOST
45
+ port = request.uri.port || DEFAULT_PORT
46
+ http_client = build_http_client(host, port)
47
+ http_client.use_ssl = request.uri.scheme.eql?("https")
48
+ http_client.request(request)
46
49
  rescue *NETWORK_ERRORS => e
47
- raise NetworkError.new("Network error: #{e.message}", response: response)
50
+ raise NetworkError, "Network error: #{e}"
48
51
  end
49
52
 
50
- def base_uri=(base_url)
51
- base_uri = URI(base_url)
52
- raise ArgumentError, "Invalid base URL" unless base_uri.is_a?(URI::HTTPS) || base_uri.is_a?(URI::HTTP)
53
-
54
- @base_uri = base_uri
55
- update_http_client_settings
56
- end
53
+ def proxy_url=(proxy_url)
54
+ @proxy_url = proxy_url
55
+ proxy_uri = URI(proxy_url)
56
+ raise ArgumentError, "Invalid proxy URL: #{proxy_uri}" unless proxy_uri.is_a?(URI::HTTP)
57
57
 
58
- def debug_output
59
- @http_client.instance_variable_get(:@debug_output)
60
- end
61
-
62
- def configuration
63
- {
64
- base_url: base_uri.to_s,
65
- open_timeout: open_timeout,
66
- read_timeout: read_timeout,
67
- write_timeout: write_timeout,
68
- proxy_url: proxy_uri.to_s,
69
- debug_output: debug_output
70
- }
58
+ @proxy_uri = proxy_uri
71
59
  end
72
60
 
73
61
  private
74
62
 
75
- def apply_http_client_settings(open_timeout:, read_timeout:, write_timeout:, debug_output:)
76
- @http_client.open_timeout = open_timeout
77
- @http_client.read_timeout = read_timeout
78
- @http_client.write_timeout = write_timeout
79
- @http_client.set_debug_output(debug_output) if debug_output
80
- end
81
-
82
- def current_http_client_settings
83
- {
84
- open_timeout: @http_client.open_timeout,
85
- read_timeout: @http_client.read_timeout,
86
- write_timeout: @http_client.write_timeout,
87
- debug_output: debug_output
88
- }
89
- end
90
-
91
- def update_http_client_settings
92
- conditionally_apply_http_client_settings do
93
- host = @base_uri.host || DEFAULT_HOST
94
- port = @base_uri.port || DEFAULT_PORT
95
- @http_client = build_http_client(host: host, port: port)
96
- @http_client.use_ssl = @base_uri.scheme == "https"
97
- end
98
- end
99
-
100
- def build_http_client(host:, port:)
101
- if defined?(@proxy_uri)
102
- Net::HTTP.new(host, port, @proxy_uri&.host, @proxy_uri&.port, @proxy_uri&.user, @proxy_uri&.password)
63
+ def build_http_client(host = DEFAULT_HOST, port = DEFAULT_PORT)
64
+ http_client = if proxy_uri
65
+ Net::HTTP.new(host, port, proxy_host, proxy_port, proxy_user, proxy_pass)
103
66
  else
104
67
  Net::HTTP.new(host, port)
105
68
  end
69
+ configure_http_client(http_client)
106
70
  end
107
71
 
108
- def conditionally_apply_http_client_settings
109
- if defined?(@http_client)
110
- settings = current_http_client_settings
111
- yield
112
- apply_http_client_settings(**settings)
113
- else
114
- yield
72
+ def configure_http_client(http_client)
73
+ http_client.tap do |c|
74
+ c.open_timeout = open_timeout
75
+ c.read_timeout = read_timeout
76
+ c.write_timeout = write_timeout
77
+ c.set_debug_output(debug_output)
115
78
  end
116
79
  end
117
80
  end
@@ -0,0 +1,5 @@
1
+ require_relative "server_error"
2
+
3
+ module X
4
+ class BadGateway < ServerError; end
5
+ end
@@ -1,5 +1,5 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module X
4
- class NotFoundError < ClientError; end
4
+ class BadRequest < ClientError; end
5
5
  end
@@ -0,0 +1,5 @@
1
+ require_relative "client_error"
2
+
3
+ module X
4
+ class ConnectionException < ClientError; end
5
+ end
@@ -1,12 +1,7 @@
1
- require "json"
2
-
3
1
  module X
4
2
  # Base error class
5
3
  class Error < ::StandardError
6
- attr_reader :object
7
-
8
- def initialize(msg, response:)
9
- @object = JSON.parse(response.body) if response&.body && !response.body.empty?
4
+ def initialize(msg, _response = nil)
10
5
  super(msg)
11
6
  end
12
7
  end
@@ -1,5 +1,5 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module X
4
- class ForbiddenError < ClientError; end
4
+ class Forbidden < ClientError; end
5
5
  end
@@ -0,0 +1,5 @@
1
+ require_relative "server_error"
2
+
3
+ module X
4
+ class GatewayTimeout < ServerError; end
5
+ end
@@ -1,5 +1,5 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module X
4
- class BadRequestError < ClientError; end
4
+ class Gone < ClientError; end
5
5
  end
@@ -1,4 +1,4 @@
1
- require_relative "server_error"
1
+ require_relative "error"
2
2
 
3
3
  module X
4
4
  class NetworkError < Error; end
@@ -0,0 +1,5 @@
1
+ require_relative "client_error"
2
+
3
+ module X
4
+ class NotAcceptable < ClientError; end
5
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "client_error"
2
+
3
+ module X
4
+ class NotFound < ClientError; end
5
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "client_error"
2
+
3
+ module X
4
+ class PayloadTooLarge < ClientError; end
5
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "server_error"
2
+
3
+ module X
4
+ class ServiceUnavailable < ServerError; end
5
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "client_error"
2
+
3
+ module X
4
+ class TooManyRedirects < ClientError; end
5
+ end
@@ -0,0 +1,29 @@
1
+ require_relative "client_error"
2
+
3
+ module X
4
+ # Rate limit error
5
+ class TooManyRequests < ClientError
6
+ def initialize(msg, response)
7
+ @response = response
8
+ super(msg)
9
+ end
10
+
11
+ def limit
12
+ @response["x-rate-limit-limit"].to_i
13
+ end
14
+
15
+ def remaining
16
+ @response["x-rate-limit-remaining"].to_i
17
+ end
18
+
19
+ def reset_at
20
+ Time.at(@response["x-rate-limit-reset"].to_i)
21
+ end
22
+
23
+ def reset_in
24
+ [(reset_at - Time.now).ceil, 0].max
25
+ end
26
+
27
+ alias_method :retry_after, :reset_in
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "client_error"
2
+
3
+ module X
4
+ class Unauthorized < ClientError; end
5
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "client_error"
2
+
3
+ module X
4
+ class UnprocessableEntity < ClientError; end
5
+ end