Skip to main content

custom_error_with_metadata

🏷️ Enrich Exceptions with Context Metadata

For complex domains, embed contextual data (user IDs, request IDs, payload snapshots) directly into your exception classes. This pattern minimizes external lookups and makes logs self-descriptive.

class ApiFailureError < StandardError
attr_reader :endpoint, :status, :payload

def initialize(msg = nil, endpoint:, status:, payload:)
super(msg || "API call failed")
@endpoint = endpoint
@status = status
@payload = payload
end

def to_h
{ message: message, endpoint: endpoint, status: status, payload: payload }
end
end

# Usage
begin
response = HTTP.post(url)
raise ApiFailureError.new(
endpoint: url,
status: response.code,
payload: response.body.to_json
) unless response.status.success?
rescue ApiFailureError => e
logger.error(e.to_h)
end