Skip to content

Commit edad655

Browse files
committed
Fix broker stuck in SYNCHRONIZING on DB error during rollback
When a service broker update job fails and attempts to revert the broker state, a database connection failure could cause the job to crash without properly handling the original error. This left the broker stuck in SYNCHRONIZING state with a FAILED job. This change wraps the state rollback operation in error handling to catch database errors and allow the original exception to be raised and the job to be retried properly. Changes: - app/jobs/v3/services/update_broker_job.rb: Add error handling around ServiceBroker.where().update() call in rescue block to gracefully handle database disconnections during state rollback - spec/unit/jobs/v3/services/update_broker_job_spec.rb: Add test case for database disconnect during state rollback
1 parent b27da11 commit edad655

2 files changed

Lines changed: 34 additions & 3 deletions

File tree

app/jobs/v3/services/update_broker_job.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,18 @@ def perform
6666

6767
@warnings
6868
rescue StandardError => e
69-
ServiceBroker.where(id: update_request.service_broker_id).update(state: previous_broker_state)
69+
begin
70+
ServiceBroker.where(id: update_request.service_broker_id).update(state: previous_broker_state) if update_request
71+
rescue StandardError
72+
# Swallow errors during state rollback (e.g., DB connection issues)
73+
# so the original exception can be raised and the job retried
74+
end
7075

7176
raise V3::ServiceBrokerUpdate::InvalidServiceBroker.new(e.message) if e.is_a?(Sequel::ValidationFailed)
7277

73-
raise e
78+
raise
7479
ensure
75-
update_request.destroy
80+
update_request.destroy if update_request
7681
end
7782

7883
private

spec/unit/jobs/v3/services/update_broker_job_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,32 @@ module V3
446446
end
447447
end
448448

449+
context 'when database disconnects during state rollback' do
450+
before do
451+
setup_broker_with_invalid_catalog
452+
453+
# Mock the where clause to raise database error only when called from rescue block
454+
# We detect this by checking if it's being called with just an id condition
455+
call_count = 0
456+
allow(ServiceBroker).to receive(:where).and_wrap_original do |original_method, *args|
457+
call_count += 1
458+
# The rescue block calls ServiceBroker.where(id: ...).update(state: ...)
459+
# This is the only place that calls .where with just {:id => ...}
460+
if args.first.is_a?(Hash) && args.first.keys == [:id] && call_count > 1
461+
raise Sequel::DatabaseDisconnectError.new('connection lost')
462+
else
463+
original_method.call(*args)
464+
end
465+
end
466+
end
467+
468+
it 'handles the database error gracefully and re-raises the original error' do
469+
expect { job.perform }.to raise_error(::CloudController::Errors::ApiError) do |error|
470+
expect(error.message).to include('Service broker catalog is invalid')
471+
end
472+
end
473+
end
474+
449475
context 'when the broker ceases to exist during the job' do
450476
it 'raises a ServiceBrokerGone error' do
451477
broker.destroy

0 commit comments

Comments
 (0)