Exception: SecApi::Error

Inherits:
StandardError
  • Object
show all
Defined in:
lib/sec_api/errors/error.rb

Overview

Error Taxonomy (Architecture ADR-2: Error Handling Strategy)

SecApi uses a type-based retry taxonomy to distinguish retryable from non-retryable failures:

SecApi::Error (base)
├── TransientError (retryable) - Network issues, server errors, rate limits
│   ├── NetworkError    - Timeouts, connection failures, SSL errors
│   ├── ServerError     - HTTP 5xx responses
│   └── RateLimitError  - HTTP 429 responses
└── PermanentError (fail-fast) - Client errors that require code/config changes
    ├── AuthenticationError - HTTP 401, 403
    ├── NotFoundError       - HTTP 404
    └── ValidationError     - HTTP 400, 422, XBRL validation

Design rationale: The retry middleware checks ‘error.is_a?(TransientError)` to determine retry eligibility. This enables automatic recovery for temporary issues (NFR5: 95%+ recovery) while failing fast on permanent errors to avoid wasting resources.

Base error class for all sec_api errors.

All errors include a request_id for correlation with logs and instrumentation callbacks. When request_id is present, error messages are automatically prefixed with [request_id] for easy log correlation.

Examples:

Accessing request_id from error

begin
  client.query.ticker("AAPL").search
rescue SecApi::Error => e
  logger.error("Request failed", request_id: e.request_id, error: e.message)
  Bugsnag.notify(e, request_id: e.request_id)
end

Error message format with request_id

# When request_id is present:
# => "[abc123-def456] Rate limit exceeded (429 Too Many Requests)."
#
# When request_id is nil or empty:
# => "Rate limit exceeded (429 Too Many Requests)."

Correlating with distributed tracing

begin
  client.query.ticker("AAPL").search
rescue SecApi::Error => e
  # The request_id matches the trace ID from your APM system
  # if you configured external request_id via custom middleware
  Datadog.tracer.active_span&.set_tag('sec_api.request_id', e.request_id)
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(message = nil, request_id: nil) ⇒ Error

Creates a new error with optional request correlation ID.

Parameters:

  • message (String) (defaults to: nil)

    Error message

  • request_id (String, nil) (defaults to: nil)

    Request correlation ID for tracing



59
60
61
62
# File 'lib/sec_api/errors/error.rb', line 59

def initialize(message = nil, request_id: nil)
  @request_id = request_id
  super(build_message(message))
end

Instance Attribute Details

#request_idString? (readonly)

The unique request correlation ID for this error.

Returns:

  • (String, nil)

    UUID request ID, or nil if not available



53
54
55
# File 'lib/sec_api/errors/error.rb', line 53

def request_id
  @request_id
end