Module: Ghostcrawl
- Defined in:
- lib/ghostcrawl.rb,
lib/ghostcrawl/client.rb,
lib/ghostcrawl/errors.rb,
lib/ghostcrawl/version.rb,
lib/ghostcrawl/error_codes.rb,
lib/ghostcrawl/client.rb
Overview
Mirrors ghostcrawl/errors/codes.json (the single source of truth). Do not hand-diverge the set.
Two channels:
PROBLEM — OUR failure -> non-2xx application/problem+json
RESULT — TARGET failure -> HTTP 200 + result_error{code,retryable}
Defined Under Namespace
Modules: ErrorCodes, KiotaParseNodeFix, KiotaWriterFix, ResponseHelper Classes: APIError, AdditionalDataBody, AuthenticationError, Client, CrawlRunsClient, DatasetsClient, GhostcrawlError, InvalidRequestError, KVClient, PaymentRequiredError, ProfilesClient, RateLimitError, RecordingsClient, SchedulesClient, ScrapeError, SessionsClient, StaticTokenProvider, WebhooksClient
Constant Summary collapse
- VERSION =
"2.2.3"- DEFAULT_BASE_URL =
"https://api.ghostcrawl.io"
Class Method Summary collapse
- .extract_status(err) ⇒ Object private
- .friendly_message(status, err) ⇒ Object private
-
.new(token: nil, base_url: nil) ⇒ Client
Convenience constructor.
-
.parse_problem_body(body) ⇒ Object
private
Best-effort parse of a problem+json body/message string.
-
.raise_translated(err) ⇒ GhostcrawlError
private
Translates a low-level transport exception (raised by the Kiota Faraday adapter) into a typed GhostcrawlError.
Class Method Details
.extract_status(err) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
118 119 120 121 122 |
# File 'lib/ghostcrawl/errors.rb', line 118 def self.extract_status(err) # The Faraday adapter appends ":<code>" to its ApiError message. m = err..to_s.match(/:(\d{3})\b/) m ? m[1].to_i : 0 end |
.friendly_message(status, err) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/ghostcrawl/errors.rb', line 125 def self.(status, err) return "validation error (HTTP 422)" if err.class.name.to_s.include?("HTTPValidationError") case status when 401, 403 then "authentication failed — check your API key (HTTP #{status})" when 402 then "payment required — usage or spend limit reached (HTTP 402)" when 400, 422 then "invalid request parameters (HTTP #{status})" when 429 then "rate limit reached — retry after a short delay (HTTP 429)" when 500..599 then "server error (HTTP #{status})" else err..to_s end end |
.new(token: nil, base_url: nil) ⇒ Client
Convenience constructor.
14 15 16 |
# File 'lib/ghostcrawl.rb', line 14 def self.new(token: nil, base_url: nil) Client.new(token: token, base_url: base_url) end |
.parse_problem_body(body) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Best-effort parse of a problem+json body/message string. Returns the parsed Hash when the text is a JSON object, or an empty Hash otherwise — never raises, so callers can read +["code"]+/+["instance"]+ unconditionally.
108 109 110 111 112 113 114 115 |
# File 'lib/ghostcrawl/errors.rb', line 108 def self.parse_problem_body(body) return {} if body.nil? parsed = JSON.parse(body.to_s) parsed.is_a?(Hash) ? parsed : {} rescue StandardError {} end |
.raise_translated(err) ⇒ GhostcrawlError
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Translates a low-level transport exception (raised by the Kiota Faraday
adapter) into a typed GhostcrawlError. The adapter raises a bare
MicrosoftKiotaAbstractions::ApiError whose message embeds the HTTP status
code (e.g. "...status code...:402"), and a typed HTTPValidationError for
422 responses. Neither subclasses GhostcrawlError, so the documented
rescue Ghostcrawl::GhostcrawlError contract would otherwise never fire.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/ghostcrawl/errors.rb', line 71 def self.raise_translated(err) # A typed HTTPValidationError is the adapter's 422 mapping — it carries no # ":<code>" in its message, so key off the class name. validation = err.class.name.to_s.include?("HTTPValidationError") status = validation ? 422 : extract_status(err) body = err. # The problem+json body is frequently dropped by the Kiota runtime before it # raises (no spec error-mapping for the status). Try to read a canonical # +code+ and +instance+ (request id) from whatever message/body text exists; # otherwise fall back to a status -> code map so the caller still gets a # canonical, documented code + retryability keyed off the status line. problem = parse_problem_body(body) code = problem["code"] || ErrorCodes.code_for_status(status) request_id = problem["instance"] retryable = ErrorCodes::RETRYABLE.fetch(code, false) # Keep the existing status -> class selection for back-compat; just enrich # the raised instance with the canonical code/retryable/request_id. klass = case status when 401, 403 then AuthenticationError when 402 then PaymentRequiredError when 400, 422 then InvalidRequestError when 429 then RateLimitError when 500..599 then APIError else GhostcrawlError end raise klass.new((status, err), status_code: status, body: body, code: code, retryable: retryable, request_id: request_id) end |