Class: Html2rss::RequestService::BotasaurusContract::ParsedResponse
- Inherits:
-
Object
- Object
- Html2rss::RequestService::BotasaurusContract::ParsedResponse
- Defined in:
- lib/html2rss/request_service/botasaurus_contract.rb
Overview
Parsed Botasaurus response wrapper.
Constant Summary collapse
- DEFAULT_HEADERS =
Fallback headers when upstream omits response headers.
{ 'content-type' => 'text/html' }.freeze
- MAX_XHR_BODY_BYTES =
Per-body size cap for captured XHR JSON (defense-in-depth vs upstream).
500_000- MAX_XHR_AGGREGATE_BYTES =
Aggregate size cap across all captured XHR bodies.
2_000_000
Instance Method Summary collapse
-
#challenge_block? ⇒ Boolean
True when upstream classified request as challenge blocked.
-
#challenge_message ⇒ String
Normalized challenge error message.
-
#final_url ⇒ String?
Final URL reported by upstream.
-
#headers ⇒ Hash{String => String}
Normalized response headers.
-
#html ⇒ String
Rendered HTML body from Botasaurus.
-
#initialize(payload:, transport_status:) ⇒ ParsedResponse
constructor
A new instance of ParsedResponse.
-
#status ⇒ Integer
Resolved status code (payload status_code or transport status).
-
#transport_meta ⇒ Hash{String => Object}
Allowlisted upstream telemetry (frozen).
-
#upstream_failure? ⇒ Boolean
True when upstream returned non-200 or an error payload.
-
#upstream_failure_message ⇒ String
Actionable upstream failure summary.
-
#xhr_responses ⇒ Array<Hash{String => Object}>
Size-capped XHR/fetch captures (absent → []).
Constructor Details
#initialize(payload:, transport_status:) ⇒ ParsedResponse
Returns a new instance of ParsedResponse.
63 64 65 66 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 63 def initialize(payload:, transport_status:) @payload = payload @transport_status = transport_status end |
Instance Method Details
#challenge_block? ⇒ Boolean
Returns true when upstream classified request as challenge blocked.
69 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 69 def challenge_block? = error_category == 'challenge_block' |
#challenge_message ⇒ String
Returns normalized challenge error message.
77 78 79 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 77 def error || 'Botasaurus challenge block detected.' end |
#final_url ⇒ String?
Returns final URL reported by upstream.
114 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 114 def final_url = payload['final_url'] |
#headers ⇒ Hash{String => String}
Returns normalized response headers.
100 101 102 103 104 105 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 100 def headers raw_headers = payload['headers'] return DEFAULT_HEADERS.dup unless raw_headers.is_a?(Hash) && raw_headers.any? raw_headers.to_h { |key, value| [key.to_s, value.to_s] } end |
#html ⇒ String
Returns rendered HTML body from Botasaurus.
92 93 94 95 96 97 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 92 def html value = payload['html'] raise BotasaurusServiceError, "Botasaurus response missing required 'html' field" if value.nil? value.to_s end |
#status ⇒ Integer
Returns resolved status code (payload status_code or transport status).
108 109 110 111 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 108 def status status_code = payload['status_code'] status_code.is_a?(Integer) ? status_code : transport_status end |
#transport_meta ⇒ Hash{String => Object}
Returns allowlisted upstream telemetry (frozen).
117 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 117 def = payload.slice(*META_KEYS).compact.freeze |
#upstream_failure? ⇒ Boolean
Returns true when upstream returned non-200 or an error payload.
72 73 74 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 72 def upstream_failure? transport_status != 200 || status != 200 || end |
#upstream_failure_message ⇒ String
Returns actionable upstream failure summary.
82 83 84 85 86 87 88 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 82 def details = ["status=#{status}"] details << "error_category=#{error_category}" if error_category details << "error=#{error}" if error details << "request_id=#{request_id}" if request_id "Botasaurus scrape failed (#{details.join(', ')})." end |
#xhr_responses ⇒ Array<Hash{String => Object}>
Returns size-capped XHR/fetch captures (absent → []).
120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/html2rss/request_service/botasaurus_contract.rb', line 120 def xhr_responses raw = payload['xhr_responses'] return [] unless raw.is_a?(Array) aggregate_bytes = 0 raw.filter_map do |entry| normalized = normalize_xhr_entry(entry) next unless normalized next unless (aggregate_bytes = advance_xhr_budget(normalized, aggregate_bytes)) normalized end end |