Module: GetStreamRuby::ErrorMapping
- Defined in:
- lib/getstream_ruby/error_mapping.rb
Overview
Translates HTTP responses and Faraday errors into SDK exceptions.
Class Method Summary collapse
- .api_error_attrs(model, status, raw_body) ⇒ Object
- .build_task_error(task_id, error_payload) ⇒ Object
- .classify_connection_failure(error) ⇒ Object
- .classify_faraday_error(error) ⇒ Object
- .lookup(hash, key) ⇒ Object
- .parse_error_body(body) ⇒ Object
-
.parse_retry_after(header) ⇒ Object
Parse Retry-After header.
-
.raise_api_error(response) ⇒ Object
Raises the appropriate ‘ApiError` / `RateLimitError` for a non-2xx `Faraday::Response`.
- .response_header(response, name) ⇒ Object
- .stringify_body(body) ⇒ Object
Class Method Details
.api_error_attrs(model, status, raw_body) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/getstream_ruby/error_mapping.rb', line 45 def api_error_attrs(model, status, raw_body) { message: model. || "Request failed with status #{status}", status_code: status, code: model.code || 0, exception_fields: model.exception_fields || {}, unrecoverable: model.unrecoverable.nil? ? false : model.unrecoverable, raw_response_body: raw_body, more_info: model.more_info, details: model.details, } end |
.build_task_error(task_id, error_payload) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/getstream_ruby/error_mapping.rb', line 123 def build_task_error(task_id, error_payload) hash = if error_payload.respond_to?(:to_h) error_payload.to_h else error_payload || {} end TaskError.new( task_id: task_id, error_type: lookup(hash, :type) || '', description: lookup(hash, :description) || '', stack_trace: lookup(hash, :stacktrace), version: lookup(hash, :version), ) end |
.classify_connection_failure(error) ⇒ Object
113 114 115 116 117 118 119 120 121 |
# File 'lib/getstream_ruby/error_mapping.rb', line 113 def classify_connection_failure(error) wrapped = error.respond_to?(:wrapped_exception) ? error.wrapped_exception : nil case wrapped when SocketError 'dns_failure' else 'connection_reset' end end |
.classify_faraday_error(error) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/getstream_ruby/error_mapping.rb', line 100 def classify_faraday_error(error) case error when Faraday::TimeoutError 'timeout' when Faraday::SSLError 'tls_handshake_failed' when Faraday::ConnectionFailed classify_connection_failure(error) else 'unknown' end end |
.lookup(hash, key) ⇒ Object
138 139 140 |
# File 'lib/getstream_ruby/error_mapping.rb', line 138 def lookup(hash, key) hash[key] || hash[key.to_s] end |
.parse_error_body(body) ⇒ Object
58 59 60 61 62 63 64 65 |
# File 'lib/getstream_ruby/error_mapping.rb', line 58 def parse_error_body(body) return body if body.is_a?(Hash) return nil unless body.is_a?(String) && !body.empty? JSON.parse(body) rescue JSON::ParserError nil end |
.parse_retry_after(header) ⇒ Object
Parse Retry-After header. Returns Float seconds. Returns nil when absent or unparseable. Past HTTP-dates clamp to 0.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/getstream_ruby/error_mapping.rb', line 84 def parse_retry_after(header) return nil if header.nil? value = header.to_s.strip return nil if value.empty? return value.to_f if value.match?(/\A\d+\z/) begin target = Time.httpdate(value) delta = target - Time.now delta.negative? ? 0.0 : delta.to_f rescue ArgumentError nil end end |
.raise_api_error(response) ⇒ Object
Raises the appropriate ‘ApiError` / `RateLimitError` for a non-2xx `Faraday::Response`.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/getstream_ruby/error_mapping.rb', line 15 def raise_api_error(response) parsed_body = parse_error_body(response.body) raw_body = stringify_body(response.body) if parsed_body.is_a?(Hash) api_error = GetStream::Generated::Models::APIError.new(parsed_body) attrs = api_error_attrs(api_error, response.status, raw_body) if response.status == 429 raise RateLimitError.new( retry_after: parse_retry_after(response_header(response, 'Retry-After')), **attrs, ) end raise ApiError.new(**attrs) end raise ApiError.new( message: 'failed to parse error response', status_code: response.status, code: 0, exception_fields: {}, unrecoverable: false, raw_response_body: raw_body, more_info: nil, details: nil, ) end |
.response_header(response, name) ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/getstream_ruby/error_mapping.rb', line 74 def response_header(response, name) headers = response.headers return nil if headers.nil? # Faraday normalizes header names to lowercase, but tolerate either form. headers[name] || headers[name.downcase] || headers[name.to_s] end |
.stringify_body(body) ⇒ Object
67 68 69 70 71 72 |
# File 'lib/getstream_ruby/error_mapping.rb', line 67 def stringify_body(body) return '' if body.nil? return body if body.is_a?(String) body.to_json end |