mirror of
https://github.com/we-promise/sure.git
synced 2026-04-17 19:14:11 +00:00
Implement Requested Fixes for CoinStats Integration (#621)
* Fix(CoinStats): Add provider network exception handling * Fix(CoinStats): Don't expose HTTP response to user * Fix(CoinStats): Migrate syncer strings to locale files
This commit is contained in:
@@ -12,11 +12,11 @@ class CoinstatsItem::Syncer
|
||||
# @param sync [Sync] Sync record for status tracking
|
||||
def perform_sync(sync)
|
||||
# Phase 1: Import data from CoinStats API
|
||||
sync.update!(status_text: "Importing wallets from CoinStats...") if sync.respond_to?(:status_text)
|
||||
sync.update!(status_text: I18n.t("models.coinstats_item.syncer.importing_wallets")) if sync.respond_to?(:status_text)
|
||||
coinstats_item.import_latest_coinstats_data
|
||||
|
||||
# Phase 2: Check account setup status and collect sync statistics
|
||||
sync.update!(status_text: "Checking wallet configuration...") if sync.respond_to?(:status_text)
|
||||
sync.update!(status_text: I18n.t("models.coinstats_item.syncer.checking_configuration")) if sync.respond_to?(:status_text)
|
||||
total_accounts = coinstats_item.coinstats_accounts.count
|
||||
|
||||
linked_accounts = coinstats_item.coinstats_accounts.joins(:account_provider).joins(:account).merge(Account.visible)
|
||||
@@ -30,18 +30,18 @@ class CoinstatsItem::Syncer
|
||||
|
||||
if unlinked_accounts.any?
|
||||
coinstats_item.update!(pending_account_setup: true)
|
||||
sync.update!(status_text: "#{unlinked_accounts.count} wallets need setup...") if sync.respond_to?(:status_text)
|
||||
sync.update!(status_text: I18n.t("models.coinstats_item.syncer.wallets_need_setup", count: unlinked_accounts.count)) if sync.respond_to?(:status_text)
|
||||
else
|
||||
coinstats_item.update!(pending_account_setup: false)
|
||||
end
|
||||
|
||||
# Phase 3: Process holdings for linked accounts only
|
||||
if linked_accounts.any?
|
||||
sync.update!(status_text: "Processing holdings...") if sync.respond_to?(:status_text)
|
||||
sync.update!(status_text: I18n.t("models.coinstats_item.syncer.processing_holdings")) if sync.respond_to?(:status_text)
|
||||
coinstats_item.process_accounts
|
||||
|
||||
# Phase 4: Schedule balance calculations for linked accounts
|
||||
sync.update!(status_text: "Calculating balances...") if sync.respond_to?(:status_text)
|
||||
sync.update!(status_text: I18n.t("models.coinstats_item.syncer.calculating_balances")) if sync.respond_to?(:status_text)
|
||||
coinstats_item.schedule_account_syncs(
|
||||
parent_sync: sync,
|
||||
window_start_date: sync.window_start_date,
|
||||
|
||||
@@ -25,6 +25,9 @@ class Provider::Coinstats < Provider
|
||||
res = self.class.get("#{BASE_URL}/wallet/blockchains", headers: auth_headers)
|
||||
handle_response(res)
|
||||
end
|
||||
rescue SocketError, Net::OpenTimeout, Net::ReadTimeout => e
|
||||
Rails.logger.error "CoinStats API: GET /wallet/blockchains failed: #{e.class}: #{e.message}"
|
||||
raise Error, "CoinStats API request failed: #{e.message}"
|
||||
end
|
||||
|
||||
# Returns blockchain options formatted for select dropdowns
|
||||
@@ -75,6 +78,9 @@ class Provider::Coinstats < Provider
|
||||
)
|
||||
handle_response(res)
|
||||
end
|
||||
rescue SocketError, Net::OpenTimeout, Net::ReadTimeout => e
|
||||
Rails.logger.error "CoinStats API: GET /wallet/balances failed: #{e.class}: #{e.message}"
|
||||
raise Error, "CoinStats API request failed: #{e.message}"
|
||||
end
|
||||
|
||||
# Extract balance data for a specific wallet from bulk response
|
||||
@@ -114,6 +120,9 @@ class Provider::Coinstats < Provider
|
||||
)
|
||||
handle_response(res)
|
||||
end
|
||||
rescue SocketError, Net::OpenTimeout, Net::ReadTimeout => e
|
||||
Rails.logger.error "CoinStats API: GET /wallet/transactions failed: #{e.class}: #{e.message}"
|
||||
raise Error, "CoinStats API request failed: #{e.message}"
|
||||
end
|
||||
|
||||
# Extract transaction data for a specific wallet from bulk response
|
||||
@@ -162,23 +171,36 @@ class Provider::Coinstats < Provider
|
||||
when 200
|
||||
JSON.parse(response.body, symbolize_names: true)
|
||||
when 400
|
||||
raise Error, "CoinStats: #{response.code} Bad Request - Invalid parameters or request format #{response.body}"
|
||||
log_api_error(response, "Bad Request")
|
||||
raise Error, "CoinStats: Invalid request parameters"
|
||||
when 401
|
||||
raise Error, "CoinStats: #{response.code} Unauthorized - Invalid or missing API key #{response.body}"
|
||||
log_api_error(response, "Unauthorized")
|
||||
raise Error, "CoinStats: Invalid or missing API key"
|
||||
when 403
|
||||
raise Error, "CoinStats: #{response.code} Forbidden - #{response.body}"
|
||||
log_api_error(response, "Forbidden")
|
||||
raise Error, "CoinStats: Access denied"
|
||||
when 404
|
||||
raise Error, "CoinStats: #{response.code} Not Found - Resource not found #{response.body}"
|
||||
log_api_error(response, "Not Found")
|
||||
raise Error, "CoinStats: Resource not found"
|
||||
when 409
|
||||
raise Error, "CoinStats: #{response.code} Conflict - Resource conflict #{response.body}"
|
||||
log_api_error(response, "Conflict")
|
||||
raise Error, "CoinStats: Resource conflict"
|
||||
when 429
|
||||
raise Error, "CoinStats: #{response.code} Too Many Requests - Rate limit exceeded #{response.body}"
|
||||
log_api_error(response, "Too Many Requests")
|
||||
raise Error, "CoinStats: Rate limit exceeded, try again later"
|
||||
when 500
|
||||
raise Error, "CoinStats: #{response.code} Internal Server Error - Server error #{response.body}"
|
||||
log_api_error(response, "Internal Server Error")
|
||||
raise Error, "CoinStats: Server error, try again later"
|
||||
when 503
|
||||
raise Error, "CoinStats: #{response.code} Service Unavailable - #{response.body}"
|
||||
log_api_error(response, "Service Unavailable")
|
||||
raise Error, "CoinStats: Service temporarily unavailable"
|
||||
else
|
||||
raise Error, "CoinStats: #{response.code} Unexpected Error - #{response.body}"
|
||||
log_api_error(response, "Unexpected Error")
|
||||
raise Error, "CoinStats: An unexpected error occurred"
|
||||
end
|
||||
end
|
||||
|
||||
def log_api_error(response, error_type)
|
||||
Rails.logger.error "CoinStats API: #{response.code} #{error_type} - #{response.body}"
|
||||
end
|
||||
end
|
||||
|
||||
10
config/locales/models/coinstats_item/en.yml
Normal file
10
config/locales/models/coinstats_item/en.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
en:
|
||||
models:
|
||||
coinstats_item:
|
||||
syncer:
|
||||
importing_wallets: Importing wallets from CoinStats...
|
||||
checking_configuration: Checking wallet configuration...
|
||||
wallets_need_setup: "%{count} wallets need setup..."
|
||||
processing_holdings: Processing holdings...
|
||||
calculating_balances: Calculating balances...
|
||||
Reference in New Issue
Block a user