Skip to content
This repository was archived by the owner on Jun 2, 2021. It is now read-only.

Commit 4049f82

Browse files
authored
v3(services) Make sure the LO state is failed when job fails (cloudfoundry#1903)
* v3(services) Make sure the LO state is failed when job fails Sometimes the Job can fail for unexpected reasons. In any failure we should make sure to leave the LO state as 'failed' [#175264299](https://www.pivotaltracker.com/story/show/175264299) * Renamed the BindingGone error to BindingNotFound BindingGone could have been missunderstood as response to 410 error * Revert accidental rename
1 parent 2e565a7 commit 4049f82

2 files changed

Lines changed: 31 additions & 4 deletions

File tree

app/jobs/v3/create_binding_async_job.rb

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
module VCAP::CloudController
88
module V3
99
class CreateBindingAsyncJob < Jobs::ReoccurringJob
10+
class BindingNotFound < CloudController::Errors::ApiError; end
11+
1012
def initialize(type, precursor_guid, parameters:, user_audit_info:, audit_hash:)
1113
super()
1214
@type = type
@@ -50,7 +52,7 @@ def resource_type
5052
end
5153

5254
def perform
53-
gone! unless resource
55+
not_found! unless resource
5456

5557
compute_maximum_duration
5658

@@ -70,9 +72,12 @@ def perform
7072
if polling_status[:retry_after].present?
7173
self.polling_interval_seconds = polling_status[:retry_after]
7274
end
75+
rescue BindingNotFound => e
76+
raise e
7377
rescue ServiceBindingCreate::BindingNotRetrievable
7478
raise CloudController::Errors::ApiError.new_from_details('ServiceBindingInvalid', 'The broker responded asynchronously but does not support fetching binding data')
7579
rescue => e
80+
save_failure(e.message)
7681
raise CloudController::Errors::ApiError.new_from_details('UnableToPerform', 'bind', e.message)
7782
end
7883

@@ -98,8 +103,21 @@ def compute_maximum_duration
98103
self.maximum_duration_seconds = max_poll_duration_on_plan
99104
end
100105

101-
def gone!
102-
raise CloudController::Errors::ApiError.new_from_details('ResourceNotFound', "The binding could not be found: #{@resource_guid}")
106+
def not_found!
107+
raise BindingNotFound.new_from_details('ResourceNotFound', "The binding could not be found: #{@resource_guid}")
108+
end
109+
110+
def save_failure(error_message)
111+
if resource.reload.last_operation.state != 'failed'
112+
resource.save_with_attributes_and_new_operation(
113+
{},
114+
{
115+
type: operation_type,
116+
state: 'failed',
117+
description: error_message,
118+
}
119+
)
120+
end
103121
end
104122
end
105123
end

spec/support/shared_examples/jobs/create_binding_job.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def test_retry_after(value, expected)
180180
binding.destroy
181181

182182
expect { subject.perform }.to raise_error(
183-
CloudController::Errors::ApiError,
183+
VCAP::CloudController::V3::CreateBindingAsyncJob::BindingNotFound,
184184
/The binding could not be found/,
185185
)
186186
end
@@ -194,6 +194,10 @@ def test_retry_after(value, expected)
194194
CloudController::Errors::ApiError,
195195
'bind could not be completed: StandardError',
196196
)
197+
198+
binding.reload
199+
expect(binding.last_operation.type).to eq('create')
200+
expect(binding.last_operation.state).to eq('failed')
197201
end
198202
end
199203

@@ -205,13 +209,18 @@ def test_retry_after(value, expected)
205209
CloudController::Errors::ApiError,
206210
'bind could not be completed: StandardError',
207211
)
212+
213+
binding.reload
214+
expect(binding.last_operation.type).to eq('create')
215+
expect(binding.last_operation.state).to eq('failed')
208216
end
209217
end
210218
end
211219

212220
describe '#handle_timeout' do
213221
it 'updates the last operation to failed' do
214222
subject.handle_timeout
223+
215224
binding.reload
216225
expect(binding.last_operation.type).to eq('create')
217226
expect(binding.last_operation.state).to eq('failed')

0 commit comments

Comments
 (0)