Module: Tabscanner::HttpClient

Included in:
Credits
Defined in:
lib/tabscanner/http_client.rb

Overview

Shared HTTP client functionality for Tabscanner API requests

This module provides common HTTP connection building, error handling, and logging functionality used across Request, Result, and Credits classes.

Examples:

Include in a class

class MyAPIClass
  extend Tabscanner::HttpClient
end

Instance Method Summary collapse

Instance Method Details

#build_connection(config, additional_headers: {}) ⇒ Faraday::Connection

Build Faraday connection with proper configuration

Parameters:

  • config (Config)

    Configuration instance

  • additional_headers (Hash) (defaults to: {})

    Additional headers to include

Returns:

  • (Faraday::Connection)

    Configured connection



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/tabscanner/http_client.rb', line 21

def build_connection(config, additional_headers: {})
  base_url = config.base_url || "https://api.tabscanner.com"
  
  Faraday.new(url: base_url) do |f|
    f.request :url_encoded
    f.adapter Faraday.default_adapter
    f.headers['apikey'] = config.api_key
    f.headers['User-Agent'] = "Tabscanner Ruby Gem #{Tabscanner::VERSION}"
    
    # Merge any additional headers
    additional_headers.each { |key, value| f.headers[key] = value }
  end
end

#build_raw_response_data(response) ⇒ Hash

Build raw response data for error debugging

Parameters:

  • response (Faraday::Response)

    HTTP response

Returns:

  • (Hash)

    Raw response data



38
39
40
41
42
43
44
# File 'lib/tabscanner/http_client.rb', line 38

def build_raw_response_data(response)
  {
    status: response.status,
    headers: response.headers.to_hash,
    body: response.body
  }
end

#handle_response_with_common_errors(response, &success_handler) ⇒ Object

Handle common HTTP status codes with appropriate errors

Parameters:

  • response (Faraday::Response)

    HTTP response

  • success_handler (Proc)

    Block to handle successful responses

Returns:

  • (Object)

    Result from success_handler

Raises:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/tabscanner/http_client.rb', line 66

def handle_response_with_common_errors(response, &success_handler)
  raw_response = build_raw_response_data(response)
  
  case response.status
  when 200, 201
    success_handler.call(response)
  when 401
    raise UnauthorizedError.new("Invalid API key or authentication failed", raw_response: raw_response)
  when 500..599
    error_message = parse_error_message(response) || "Server error occurred"
    raise ServerError.new(error_message, raw_response: raw_response)
  else
    error_message = parse_error_message(response) || "Request failed with status #{response.status}"
    raise Error.new(error_message, raw_response: raw_response)
  end
end

#log_request_response(method, endpoint, response, config) ⇒ Object

Log request and response details for debugging

Parameters:

  • method (String)

    HTTP method

  • endpoint (String)

    API endpoint

  • response (Faraday::Response)

    HTTP response

  • config (Config)

    Configuration instance



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/tabscanner/http_client.rb', line 88

def log_request_response(method, endpoint, response, config)
  logger = config.logger
  
  # Log request details
  logger.debug("HTTP Request: #{method.upcase} #{endpoint}")
  logger.debug("Request Headers: apikey=[REDACTED], User-Agent=#{response.env.request_headers['User-Agent']}")
  
  # Log response details
  logger.debug("HTTP Response: #{response.status}")
  logger.debug("Response Headers: #{response.headers.to_hash}")
  
  # Log response body (truncated if too long)
  body = response.body
  if body && body.length > 500
    logger.debug("Response Body: #{body[0..500]}... (truncated)")
  else
    logger.debug("Response Body: #{body}")
  end
end

#parse_error_message(response) ⇒ String?

Parse error message from response

Parameters:

  • response (Faraday::Response)

    HTTP response

Returns:

  • (String, nil)

    Error message if available



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/tabscanner/http_client.rb', line 49

def parse_error_message(response)
  return nil if response.body.nil? || response.body.empty?

  begin
    data = JSON.parse(response.body)
    data['error'] || data['message'] || data['errors']&.first
  rescue JSON::ParserError
    # If JSON parsing fails, return raw body if it's short enough
    response.body.length < 200 ? response.body : nil
  end
end