{"record":{"id":"c5b26f8b7b59caa2","repo":"we-promise/sure","slug":"network-error-c5b26f","errorCode":"network_error","errorMessage":"Network error after #{max_retries} retries: #{e.message}","messagePattern":"Network error after #(.+?) retries: #(.+?)","errorType":"exception","errorClass":"Provider::Simplefin::SimplefinError","httpStatus":null,"severity":"error","filePath":"app/models/provider/simplefin.rb","lineNumber":154,"sourceCode":"      begin\n        yield\n      rescue *RETRYABLE_ERRORS => e\n        retries += 1\n\n        if retries <= max_retries\n          delay = calculate_retry_delay(retries)\n          Rails.logger.warn(\n            \"SimpleFin API: #{operation_name} failed (attempt #{retries}/#{max_retries}): \" \\\n            \"#{e.class}: #{e.message}. Retrying in #{delay}s...\"\n          )\n          sleep(delay) if backoff && delay.to_f.positive?\n          retry\n        else\n          Rails.logger.error(\n            \"SimpleFin API: #{operation_name} failed after #{max_retries} retries: \" \\\n            \"#{e.class}: #{e.message}\"\n          )\n          raise SimplefinError.new(\n            \"Network error after #{max_retries} retries: #{e.message}\",\n            :network_error\n          )\n        end\n      rescue SimplefinError => e\n        # Preserve original error type and message.\n        raise\n      rescue => e\n        # Non-retryable errors are logged and re-raised immediately\n        Rails.logger.error \"SimpleFin API: #{operation_name} failed with non-retryable error: #{e.class}: #{e.message}\"\n        raise SimplefinError.new(\"Exception during #{operation_name}: #{e.message}\", :request_failed)\n      end\n    end\n\n    # Calculate delay with exponential backoff and jitter\n    def calculate_retry_delay(retry_count)\n      # Exponential backoff: 2^retry * initial_delay\n      base_delay = INITIAL_RETRY_DELAY * (2 ** (retry_count - 1))","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/provider/simplefin.rb#L136-L172","documentation":"Raised by Provider::Simplefin.with_retries when a retryable network exception (connection reset, timeout, DNS failure, etc.) persists past MAX_RETRIES attempts. Each attempt logged a warning with the exception class and the exponential-backoff delay before sleeping and retrying; after the final failure an error is logged and SimplefinError(:network_error) wraps the last exception's message.","triggerScenarios":"Three consecutive network-level failures while calling the SimpleFIN access URL: Errno::ECONNRESET, Errno::ETIMEDOUT, SocketError, Net::OpenTimeout - e.g. local network down, DNS for the SimpleFIN host failing, or a firewall/middlebox dropping the connection. The HTTP request never completed, unlike server_error/fetch_failed.","commonSituations":"Developer machine lost connectivity mid-sync; outbound HTTPS blocked by corporate proxy; SimpleFIN host briefly unreachable; long-running Heroku/Rail dynes with flaky egress; DNS misresolution in Docker.","solutions":["Confirm basic reachability from the app host: curl -v the SimpleFIN base URL - if that fails, fix local network/DNS/proxy first","Re-run the operation - with exponential backoff and jitter already applied, persistent failure usually means a real connectivity problem, not a blip","Check the preceding warn logs: the exception class (SocketError vs ECONNRESET vs timeout) points at DNS vs connection-drop vs slow-server","If timeouts dominate, review the HTTParty timeout defaults in this class and the response size (very large accounts can exceed read timeouts)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  simplefin.get_accounts\nrescue Provider::Simplefin::SimplefinError => e\n  if e.error_type == :network_error\n    retry_with_backoff(max: 3) # transport failed; retry whole operation later\n  else\n    raise\n  end\nend","preventionTips":["Run syncs from hosts with verified egress to the SimpleFIN domain","Rely on the library's built-in retries for blips; add job-level retry for sustained outages","Monitor warn logs 'Retrying in ...s' as an early signal of degrading connectivity"],"tags":["simplefin","network","retries-exhausted","timeout","dns"],"backgroundTag":"network-retries-exhausted","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}