Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions lib/que/job_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ module Que
SQL[:expire_job] =
%{
UPDATE public.que_jobs
SET error_count = error_count + 1,
expired_at = now()
WHERE id = $1::bigint
SET error_count = error_count + 1,
expired_at = now(),
last_error_message = COALESCE(left($1::text, 500), last_error_message),
last_error_backtrace = COALESCE(left($2::text, 10000), last_error_backtrace)
WHERE id = $3::bigint
}

SQL[:destroy_job] =
Expand Down Expand Up @@ -101,7 +103,15 @@ def expire
return unless que_target

if id = que_target.que_attrs[:id]
Que.execute :expire_job, [id]
if e = que_target.que_error
message = "#{e.class}: #{e.message}".slice(0, 500)
backtrace = (e.backtrace || []).join("\n").slice(0, 10000)
else
message = nil
backtrace = nil
end

Que.execute :expire_job, [message, backtrace, id]
end

que_target.que_resolved = true
Expand Down
6 changes: 5 additions & 1 deletion lib/que/worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,11 @@ def work_job(metajob)
max_retry_count = job_class.resolve_que_setting(:maximum_retry_count)

if max_retry_count && error_count > max_retry_count
Que.execute :expire_job, [job.fetch(:id)]
Que.execute :expire_job, [
"#{error.class}: #{error.message}".slice(0, 500),
(error.backtrace || []).join("\n").slice(0, 10000),
job.fetch(:id),
]
else
delay =
job_class.
Expand Down
13 changes: 13 additions & 0 deletions spec/que/worker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,19 @@ def run(*args)
end
end
end

it "should record the error message and backtrace on the expired job" do
WorkerJob.maximum_retry_count = 0
job = WorkerJob.enqueue
ds = jobs_dataset.where(id: job.que_attrs[:id])

run_jobs

row = ds.first
assert_in_delta row[:expired_at], Time.now, QueSpec::TIME_SKEW
assert_equal "RuntimeError: Blah!", row[:last_error_message]
assert_match(/\A#{__FILE__}/, row[:last_error_backtrace].split("\n").first)
end
end
end

Expand Down