Class: Poodle::HttpClient
- Inherits:
-
Object
- Object
- Poodle::HttpClient
- Defined in:
- lib/poodle/http_client.rb
Overview
HTTP client wrapper for Poodle API communication
Instance Attribute Summary collapse
-
#config ⇒ Configuration
readonly
The configuration object.
Instance Method Summary collapse
-
#build_connection ⇒ Faraday::Connection
private
Build the Faraday connection.
-
#configure_connection_headers(conn) ⇒ Object
private
Configure connection headers.
-
#configure_connection_middleware(conn) ⇒ Object
private
Configure connection middleware.
-
#configure_connection_timeouts(conn) ⇒ Object
private
Configure connection timeouts.
-
#configure_custom_options(conn) ⇒ Object
private
Configure custom HTTP options.
-
#extract_error_message(response) ⇒ String
private
Extract error message from response.
-
#extract_validation_errors(body) ⇒ Hash
private
Extract validation errors from response body.
-
#get(endpoint, params = {}, headers = {}) ⇒ Hash
Send a GET request.
-
#handle_connection_failed_error(error) ⇒ Object
private
Handle connection failed errors.
-
#handle_error_response(response) ⇒ Object
private
Handle error responses.
-
#handle_forbidden_error(response) ⇒ Object
private
Handle forbidden errors (403).
-
#handle_payment_error(response) ⇒ Object
private
Handle payment errors (402).
-
#handle_response(response) ⇒ Hash
private
Handle HTTP response.
-
#handle_server_error(response) ⇒ Object
private
Handle server errors (5xx).
-
#handle_validation_error(response, status_code: 400) ⇒ Object
private
Handle validation errors (400, 422).
-
#initialize(config) ⇒ HttpClient
constructor
Initialize a new HttpClient.
-
#log_request(method, url, data) ⇒ Object
private
Log HTTP request for debugging.
-
#log_response(response) ⇒ Object
private
Log HTTP response for debugging.
-
#perform_request(method, url, data, headers) ⇒ Faraday::Response
private
Perform the actual HTTP request.
-
#post(endpoint, data = {}, headers = {}) ⇒ Hash
Send a POST request.
-
#request(method, endpoint, data = {}, headers = {}) ⇒ Hash
private
Send an HTTP request.
-
#success_response?(response) ⇒ Boolean
private
Check if response is successful.
Constructor Details
#initialize(config) ⇒ HttpClient
Initialize a new HttpClient
28 29 30 31 |
# File 'lib/poodle/http_client.rb', line 28 def initialize(config) @config = config @connection = build_connection end |
Instance Attribute Details
#config ⇒ Configuration (readonly)
Returns the configuration object.
23 24 25 |
# File 'lib/poodle/http_client.rb', line 23 def config @config end |
Instance Method Details
#build_connection ⇒ Faraday::Connection (private)
Build the Faraday connection
126 127 128 129 130 131 132 133 |
# File 'lib/poodle/http_client.rb', line 126 def build_connection Faraday.new do |conn| configure_connection_middleware(conn) configure_connection_timeouts(conn) configure_connection_headers(conn) (conn) end end |
#configure_connection_headers(conn) ⇒ Object (private)
Configure connection headers
155 156 157 158 159 160 |
# File 'lib/poodle/http_client.rb', line 155 def configure_connection_headers(conn) conn.headers["Authorization"] = "Bearer #{@config.api_key}" conn.headers["Content-Type"] = "application/json" conn.headers["Accept"] = "application/json" conn.headers["User-Agent"] = @config.user_agent end |
#configure_connection_middleware(conn) ⇒ Object (private)
Configure connection middleware
138 139 140 141 142 |
# File 'lib/poodle/http_client.rb', line 138 def configure_connection_middleware(conn) conn.request :json conn.response :json, content_type: /\bjson$/ conn.adapter Faraday.default_adapter end |
#configure_connection_timeouts(conn) ⇒ Object (private)
Configure connection timeouts
147 148 149 150 |
# File 'lib/poodle/http_client.rb', line 147 def configure_connection_timeouts(conn) conn..timeout = @config.timeout conn..open_timeout = @config.connect_timeout end |
#configure_custom_options(conn) ⇒ Object (private)
Configure custom HTTP options
165 166 167 168 169 |
# File 'lib/poodle/http_client.rb', line 165 def (conn) @config..each do |key, value| conn.[key] = value end end |
#extract_error_message(response) ⇒ String (private)
Extract error message from response
288 289 290 291 292 293 |
# File 'lib/poodle/http_client.rb', line 288 def (response) body = response.body return "HTTP #{response.status} error" unless body.is_a?(Hash) body["message"] || body["error"] || "HTTP #{response.status} error" end |
#extract_validation_errors(body) ⇒ Hash (private)
Extract validation errors from response body
299 300 301 302 303 304 305 306 307 |
# File 'lib/poodle/http_client.rb', line 299 def extract_validation_errors(body) return {} unless body.is_a?(Hash) errors = body["errors"] || body["validation_errors"] || {} return {} unless errors.is_a?(Hash) # Convert string values to arrays for consistency errors.transform_values { |v| Array(v) } end |
#get(endpoint, params = {}, headers = {}) ⇒ Hash
Send a GET request
51 52 53 |
# File 'lib/poodle/http_client.rb', line 51 def get(endpoint, params = {}, headers = {}) request(:get, endpoint, params, headers) end |
#handle_connection_failed_error(error) ⇒ Object (private)
Handle connection failed errors
112 113 114 115 116 117 118 119 120 121 |
# File 'lib/poodle/http_client.rb', line 112 def handle_connection_failed_error(error) if error..include?("SSL") || error..include?("certificate") raise NetworkError.ssl_error(error.) elsif error..include?("resolve") || error..include?("DNS") host = URI.parse(@config.base_url).host raise NetworkError.dns_resolution_failed(host) else raise NetworkError.connection_failed(@config.base_url, original_error: error) end end |
#handle_error_response(response) ⇒ Object (private)
Handle error responses
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/poodle/http_client.rb', line 194 def handle_error_response(response) case response.status when 400 handle_validation_error(response) when 401 raise AuthenticationError.invalid_api_key when 402 handle_payment_error(response) when 403 handle_forbidden_error(response) when 422 handle_validation_error(response, status_code: 422) when 429 raise RateLimitError.from_headers(response.headers) when 500..599 handle_server_error(response) else raise NetworkError.http_error(response.status, (response)) end end |
#handle_forbidden_error(response) ⇒ Object (private)
Handle forbidden errors (403)
251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/poodle/http_client.rb', line 251 def handle_forbidden_error(response) body = response.body || {} = (response) raise ForbiddenError. unless .include?("suspended") # Extract suspension details if available reason = body["reason"] || "unknown" rate = body["rate"] raise ForbiddenError.account_suspended(reason, rate) end |
#handle_payment_error(response) ⇒ Object (private)
Handle payment errors (402)
232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/poodle/http_client.rb', line 232 def handle_payment_error(response) = (response) case when /subscription.*expired/i raise PaymentError.subscription_expired when /trial.*limit/i raise PaymentError.trial_limit_reached when /monthly.*limit/i raise PaymentError.monthly_limit_reached else raise PaymentError, end end |
#handle_response(response) ⇒ Hash (private)
Handle HTTP response
176 177 178 179 180 |
# File 'lib/poodle/http_client.rb', line 176 def handle_response(response) return response.body || {} if success_response?(response) handle_error_response(response) end |
#handle_server_error(response) ⇒ Object (private)
Handle server errors (5xx)
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/poodle/http_client.rb', line 267 def handle_server_error(response) = (response) case response.status when 500 raise ServerError.internal_server_error() when 502 raise ServerError.bad_gateway() when 503 raise ServerError.service_unavailable() when 504 raise ServerError.gateway_timeout() else raise ServerError.new(, status_code: response.status) end end |
#handle_validation_error(response, status_code: 400) ⇒ Object (private)
Handle validation errors (400, 422)
220 221 222 223 224 225 226 |
# File 'lib/poodle/http_client.rb', line 220 def handle_validation_error(response, status_code: 400) body = response.body || {} = (response) errors = extract_validation_errors(body) raise ValidationError.new(, errors: errors, status_code: status_code) end |
#log_request(method, url, data) ⇒ Object (private)
Log HTTP request for debugging
314 315 316 317 |
# File 'lib/poodle/http_client.rb', line 314 def log_request(method, url, data) puts "[Poodle] #{method.upcase} #{url}" puts "[Poodle] Request: #{data.to_json}" unless data.empty? end |
#log_response(response) ⇒ Object (private)
Log HTTP response for debugging
322 323 324 325 |
# File 'lib/poodle/http_client.rb', line 322 def log_response(response) puts "[Poodle] Response: #{response.status}" puts "[Poodle] Body: #{response.body}" if response.body end |
#perform_request(method, url, data, headers) ⇒ Faraday::Response (private)
Perform the actual HTTP request
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/poodle/http_client.rb', line 91 def perform_request(method, url, data, headers) case method when :post @connection.post(url) do |req| req.headers.update(headers) req.body = data.to_json end when :get @connection.get(url) do |req| req.headers.update(headers) req.params = data end else raise ArgumentError, "Unsupported HTTP method: #{method}" end end |
#post(endpoint, data = {}, headers = {}) ⇒ Hash
Send a POST request
40 41 42 |
# File 'lib/poodle/http_client.rb', line 40 def post(endpoint, data = {}, headers = {}) request(:post, endpoint, data, headers) end |
#request(method, endpoint, data = {}, headers = {}) ⇒ Hash (private)
Send an HTTP request
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/poodle/http_client.rb', line 65 def request(method, endpoint, data = {}, headers = {}) url = @config.url_for(endpoint) log_request(method, url, data) if @config.debug? response = perform_request(method, url, data, headers) log_response(response) if @config.debug? handle_response(response) rescue Faraday::TimeoutError => e puts "TimeoutError: #{e.}" raise NetworkError.connection_timeout(@config.timeout) rescue Faraday::ConnectionFailed => e handle_connection_failed_error(e) rescue Faraday::Error => e raise NetworkError.connection_failed(@config.base_url, original_error: e) end |
#success_response?(response) ⇒ Boolean (private)
Check if response is successful
186 187 188 |
# File 'lib/poodle/http_client.rb', line 186 def success_response?(response) (200..299).cover?(response.status) end |