{"record":{"id":"6e1cbac651eaef8f","repo":"we-promise/sure","slug":"class-name-connectioncleanupjob-failed","errorCode":null,"errorMessage":"<%= class_name %>ConnectionCleanupJob - Failed: #{e.class} - #{e.message}","messagePattern":"<%= class_name %>ConnectionCleanupJob - Failed: #(.+?) - #(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"lib/generators/provider/family/templates/connection_cleanup_job.rb.tt","lineNumber":29,"sourceCode":"    )\n\n    <%= file_name %>_item = <%= class_name %>Item.find_by(id: <%= file_name %>_item_id)\n    return unless <%= file_name %>_item\n\n    # Check if other accounts still use this connection\n    if <%= file_name %>_item.<%= file_name %>_accounts\n         .where(<%= file_name %>_authorization_id: authorization_id)\n         .exists?\n      Rails.logger.info(\"<%= class_name %>ConnectionCleanupJob - Connection still in use, skipping\")\n      return\n    end\n\n    # Delete from provider API\n    delete_connection(<%= file_name %>_item, authorization_id)\n\n    Rails.logger.info(\"<%= class_name %>ConnectionCleanupJob - Connection #{authorization_id} deleted\")\n  rescue => e\n    Rails.logger.warn(\n      \"<%= class_name %>ConnectionCleanupJob - Failed: #{e.class} - #{e.message}\"\n    )\n    # Don't raise - cleanup failures shouldn't block other operations\n  end\n\n  private\n\n    def delete_connection(<%= file_name %>_item, authorization_id)\n      provider = <%= file_name %>_item.<%= file_name %>_provider\n      return unless provider\n\n      credentials = <%= file_name %>_item.<%= file_name %>_credentials\n      return unless credentials\n\n      # TODO: Implement API call to delete connection\n      # Example:\n      # provider.delete_connection(\n      #   authorization_id: authorization_id,","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/lib/generators/provider/family/templates/connection_cleanup_job.rb.tt#L11-L47","documentation":"Generated investment-provider variant of the connection cleanup job, enqueued from the provider account's after_destroy (enqueue_connection_cleanup). The job skips deletion when another provider account still uses the authorization, otherwise calls delete_connection, and wraps the whole perform in a broad rescue that logs class + message and deliberately does not re-raise, so cleanup failures never block account destruction or other jobs. The orphaned provider-side connection may persist.","triggerScenarios":"Any exception between job start and completion of delete_connection: database errors in the exists? query, nil-related errors if <%= file_name %>_item lookup returns something unexpected, or an error escaping delete_connection's own narrower rescue (this one catches StandardError from anywhere in perform, connection_cleanup_job.rb.tt:29).","commonSituations":"Provider API unreachable when a user deletes an account; the generated delete_connection placeholder was edited and now raises; item/credentials records in inconsistent state after partial migrations; job retried after the item row was purged.","solutions":["Use e.class and e.message from the log line to identify the failing statement (NoMethodError usually means a placeholder/SDK gap; Faraday/Net errors mean the provider API)","If the cause is in the SDK call, implement or fix delete_connection (see the TODO in the same template)","Re-run cleanup manually once the provider/DB is healthy — the still-in-use check makes it safe to retry","If provider-side orphans are unacceptable, add a follow-up reconciliation sweep that compares provider connections with local authorizations"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# Before destroy, confirm cleanup preconditions hold\ndef enqueue_connection_cleanup\n  return unless <%= file_name %>_item\n  return unless <%= file_name %>_authorization_id.present?\n  return unless <%= file_name %>_item.<%= file_name %>_credentials.present?\n\n  <%= class_name %>ConnectionCleanupJob.perform_later(...)\nend","typeGuard":null,"tryCatchPattern":"# Narrow the broad rescue: re-raise transient DB errors for Sidekiq retry, swallow the rest\nrescue ActiveRecord::StatementInvalid, ActiveRecord::ConnectionNotEstablished => e\n  Rails.logger.warn(\"<%= class_name %>ConnectionCleanupJob - transient: #{e.class}\")\n  raise # let Sidekiq retry with backoff\nrescue => e\n  Rails.logger.warn(\"<%= class_name %>ConnectionCleanupJob - Failed: #{e.class} - #{e.message}\")\nend","preventionTips":["Run cleanup jobs idempotently (the still-in-use exists? check) so manual retries after outages are safe","Alert on this warning in aggregation — silent cleanup failures accumulate provider-side orphans","Schedule a periodic reconciliation of provider connections vs local authorizations"],"tags":["background-jobs","cleanup","swallowed-error","generator-template","provider-api","rescue"],"backgroundTag":"background-job-swallowed-error","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}