Skip to content

Commit 9a1dcf1

Browse files
authored
Add log to diego stager error case (#4042)
- Without this log, the stack trace for the underlying error is lost, which makes debugging difficult - Add helper for testing log output. This makes it easier to validate the correct information is logged, without having to manually test.
1 parent eb594ee commit 9a1dcf1

File tree

4 files changed

+90
-12
lines changed

4 files changed

+90
-12
lines changed

lib/cloud_controller/diego/stager.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ def send_stage_package_request(staging_details)
3333
rescue CloudController::Errors::ApiError => e
3434
raise e
3535
rescue StandardError => e
36+
logger.error('stage.package.error',
37+
package_guid: staging_details.package.guid,
38+
staging_guid: staging_details.staging_guid,
39+
error: e,
40+
backtrace: e.backtrace)
3641
raise CloudController::Errors::ApiError.new_from_details('StagerError', e)
3742
end
3843

spec/spec_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
rspec_config.include TimeHelpers
111111
rspec_config.include LinkHelpers
112112
rspec_config.include BackgroundJobHelpers
113+
rspec_config.include LogHelpers
113114

114115
rspec_config.include ServiceBrokerHelpers
115116
rspec_config.include UserHelpers

spec/support/log_helpers.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module LogHelpers
2+
class TailedLogs
3+
def initialize(io_log)
4+
@io_log = io_log
5+
end
6+
7+
def read
8+
@io_log.string.split("\n").map { |l| Oj.load(l) }
9+
end
10+
end
11+
12+
def tail_logs(&block)
13+
steno_config_backup = ::Steno.config
14+
15+
begin
16+
io_log = ::StringIO.new
17+
io_sink = ::Steno::Sink::IO.new(io_log, codec: ::Steno::Codec::JsonRFC3339.new)
18+
::Steno.init(::Steno::Config.new(
19+
sinks: steno_config_backup.sinks + [io_sink],
20+
codec: steno_config_backup.codec,
21+
context: steno_config_backup.context,
22+
default_log_level: 'all'
23+
))
24+
25+
block.yield(TailedLogs.new(io_log))
26+
ensure
27+
::Steno.init(steno_config_backup)
28+
end
29+
end
30+
end

spec/unit/lib/cloud_controller/diego/stager_spec.rb

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,62 @@ module Diego
6464
end
6565

6666
context 'when the stage fails' do
67-
let(:error) do
68-
{ error: { id: 'StagingError', message: 'Stager error: staging failed' } }
67+
describe 'with an APIError' do
68+
let(:error) do
69+
{ error: { id: 'StagingError', message: 'Stager error: staging failed' } }
70+
end
71+
72+
before do
73+
allow(messenger).to receive(:send_stage_request).and_raise(CloudController::Errors::ApiError.new_from_details('StagerError', 'staging failed'))
74+
end
75+
76+
it 'calls the completion handler with the error' do
77+
expect do
78+
stager.stage(staging_details)
79+
end.to raise_error(CloudController::Errors::ApiError)
80+
package.reload
81+
expect(buildpack_completion_handler).to have_received(:staging_complete).with(error, false)
82+
end
6983
end
7084

71-
before do
72-
allow(messenger).to receive(:send_stage_request).and_raise(CloudController::Errors::ApiError.new_from_details('StagerError', 'staging failed'))
73-
end
74-
75-
it 'calls the completion handler with the error' do
76-
expect do
77-
stager.stage(staging_details)
78-
end.to raise_error(CloudController::Errors::ApiError)
79-
package.reload
80-
expect(buildpack_completion_handler).to have_received(:staging_complete).with(error, false)
85+
describe 'with any other error' do
86+
let(:error) do
87+
{ error: { id: 'StagingError', message: 'Stager error: something is very wrong' } }
88+
end
89+
90+
before do
91+
allow(messenger).to receive(:send_stage_request).and_raise(StandardError.new('something is very wrong'))
92+
end
93+
94+
it 'calls the completion handler with the error' do
95+
expect do
96+
stager.stage(staging_details)
97+
end.to raise_error(CloudController::Errors::ApiError)
98+
package.reload
99+
expect(buildpack_completion_handler).to have_received(:staging_complete).with(error, false)
100+
end
101+
102+
it 'logs the original error, with a stack trace' do
103+
tail_logs do |logs|
104+
expect do
105+
stager.stage(staging_details)
106+
end.to raise_error(CloudController::Errors::ApiError)
107+
108+
expect(
109+
logs.read.find { |l| l['message'] == 'stage.package.error' }
110+
).to match(
111+
hash_including(
112+
'message' => 'stage.package.error',
113+
'data' => {
114+
'package_guid' => package.guid,
115+
'staging_guid' => build.guid,
116+
'error' => 'something is very wrong',
117+
'backtrace' => array_including(/and_raise/)
118+
}
119+
)
120+
)
121+
end
122+
end
81123
end
82124
end
83125
end

0 commit comments

Comments
 (0)