Resolve #2860 - Do not ignore Job class sidekiq options while assessing retryable job#2861
Resolve #2860 - Do not ignore Job class sidekiq options while assessing retryable job#2861aovertus wants to merge 1 commit intogetsentry:masterfrom
Conversation
…e assessing retryable job
| retry_option = context.dig(:job, "retry") | ||
| retry_option ||= context.dig(:job, "class")&.safe_constantize | ||
| &.get_sidekiq_options | ||
| &.[]("retry") |
There was a problem hiding this comment.
Bug: The use of ||= in retryable? causes a job-level retry: false setting to be incorrectly overridden by the class-level retry option, potentially suppressing Sentry error reports.
Severity: HIGH
Suggested Fix
Replace the ||= operator with an explicit if retry_option.nil? check. This ensures that a false value for the retry option from the job payload is respected and not overridden by the class-level configuration.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: sentry-sidekiq/lib/sentry/sidekiq/error_handler.rb#L62-L65
Potential issue: In the `retryable?` method, the `||=` operator is used to fall back to
class-level Sidekiq options. However, `||=` treats a boolean `false` as a falsy value.
If a specific job is enqueued with `retry: false`, which is a valid job-level setting,
the code will incorrectly ignore this `false` value and instead use the retry setting
from the worker class. When `report_after_job_retries` is enabled, this causes the error
handler to incorrectly assume the job will be retried. As a result, the initial error is
suppressed, and because the job will not actually retry, the error is never reported to
Sentry at all.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| retry_option = context.dig(:job, "retry") | ||
| retry_option ||= context.dig(:job, "class")&.safe_constantize | ||
| &.get_sidekiq_options | ||
| &.[]("retry") |
There was a problem hiding this comment.
||= overrides explicit retry:false from job hash
High Severity
Using ||= to fall back to class-level sidekiq options treats an explicit "retry" => false in the job hash the same as a missing/nil "retry" key. Since false is falsy in Ruby, ||= will overwrite it with the class-level option. A job explicitly marked as non-retryable in its payload could be treated as retryable if the class defines sidekiq_options retry: true. A nil check is needed instead of ||=.
| retry_option = context.dig(:job, "retry") | ||
| retry_option ||= context.dig(:job, "class")&.safe_constantize | ||
| &.get_sidekiq_options | ||
| &.[]("retry") |
There was a problem hiding this comment.
retry_limit returns 0 for class-option-only retryable jobs
Medium Severity
When retryable? returns true based on class-level sidekiq_options (because the job hash has no "retry" key), retry_limit still only reads from context.dig(:job, "retry") which is nil. This causes retry_limit to return 0 via the else branch, making report_after_job_retries never defer reporting since retry_count < -1 is always false. The retry_limit method needs the same class-option fallback.


Description
Describe your changes:
Ensure sidekiq_options are considered while evaluating if a job is
retryable?