Skip to content

Commit 00f2285

Browse files
committed
Merge branch 'fix/DEX-2540/error-handling-fix' into 'master'
[DEX-2540] fix: enhance error logging and handling Closes DEX-2540 See merge request nstmrt/rubygems/outbox!103
2 parents e6a91d7 + 8cc8fe7 commit 00f2285

File tree

8 files changed

+66
-14
lines changed

8 files changed

+66
-14
lines changed

.gitlab-ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ tests:
2727
DATABASE_URL: postgres://postgres:secret@postgres:5432
2828
REDIS_URL: redis://redis:6379/0
2929
before_script:
30+
- gem update --system 3.4.22
3031
- bin/setup
3132
script:
3233
- bundle exec appraisal rspec --format RspecJunitFormatter --out test-results/rspec_$RUBY_VERSION.xml --format documentation

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1313

1414
### Fixed
1515

16+
## [6.10.0] - 2024-09-19
17+
18+
### Changed
19+
20+
- Renamed `backtrace` log tag to `stacktrace`
21+
22+
### Fixed
23+
24+
- Fixed handling of errors if database is not available
25+
1626
## [6.9.0] - 2024-09-13
1727

1828
### Added

app/interactors/sbmt/outbox/process_item.rb

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class ProcessItem < Sbmt::Outbox::DryInteractor
1111

1212
METRICS_COUNTERS = %i[error_counter retry_counter sent_counter fetch_error_counter discarded_counter].freeze
1313

14-
delegate :log_success, :log_failure, to: "Sbmt::Outbox.logger"
14+
delegate :log_success, :log_info, :log_failure, to: "Sbmt::Outbox.logger"
1515
delegate :item_process_middlewares, to: "Sbmt::Outbox"
1616
delegate :box_type, :box_name, :owner, to: :item_class
1717

@@ -73,7 +73,7 @@ def fetch_item
7373
end
7474

7575
unless item.for_processing?
76-
log_error("already processed")
76+
log_info("already processed")
7777
counters[:fetch_error_counter] += 1
7878
return Failure(:already_processed)
7979
end
@@ -154,7 +154,7 @@ def process_item(transport, item, payload)
154154
# rubocop:enable Metrics/MethodLength
155155

156156
def track_failed(ex_or_msg, item = nil)
157-
log_error(ex_or_msg, item)
157+
log_processing_error(ex_or_msg, item)
158158

159159
item&.touch_processed_at
160160
item&.add_error(ex_or_msg)
@@ -170,6 +170,8 @@ def track_failed(ex_or_msg, item = nil)
170170
counters[:retry_counter] += 1
171171
item.pending!
172172
end
173+
rescue => e
174+
log_error_handling_error(e, item)
173175
end
174176

175177
def track_successed(item)
@@ -196,18 +198,28 @@ def track_discarded(item)
196198
counters[:discarded_counter] += 1
197199
end
198200

199-
def log_error(ex_or_msg, item = nil)
201+
def log_processing_error(ex_or_msg, item = nil)
200202
text = format_exception_error(ex_or_msg)
201203

202204
msg = "Failed processing #{box_type} item with error: #{text}.\n" \
203205
"Record: #{item_class.name}##{item_id}.\n" \
204206
"#{item&.log_details&.to_json}"
205207

206-
log_failure(msg, backtrace: format_backtrace(ex_or_msg))
208+
log_failure(msg, stacktrace: format_backtrace(ex_or_msg))
207209
end
208210

209-
def format_exception_error(e)
210-
text = if e.respond_to?(:cause) && !e.cause.nil?
211+
def log_error_handling_error(handling_error, item = nil)
212+
text = format_exception_error(handling_error, extract_cause: false)
213+
214+
msg = "Could not persist status of failed #{box_type} item due to error: #{text}.\n" \
215+
"Record: #{item_class.name}##{item_id}.\n" \
216+
"#{item&.log_details&.to_json}"
217+
218+
log_failure(msg, stacktrace: format_backtrace(handling_error))
219+
end
220+
221+
def format_exception_error(e, extract_cause: true)
222+
text = if extract_cause && e.respond_to?(:cause) && !e.cause.nil?
211223
"#{format_exception_error(e.cause)}. "
212224
else
213225
""

lib/sbmt/outbox/v1/worker.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def log_fatal(e, job, worker_number)
218218

219219
logger.log_error(
220220
"Failed processing #{job.resource_key} with error: #{e.class} #{e.message}",
221-
backtrace: backtrace
221+
stacktrace: backtrace
222222
)
223223
end
224224

lib/sbmt/outbox/v2/box_processor.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def log_fatal(e, task)
134134

135135
logger.log_error(
136136
"Failed processing #{task} with error: #{e.class} #{e.message}",
137-
backtrace: backtrace
137+
stacktrace: backtrace
138138
)
139139
end
140140

lib/sbmt/outbox/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
module Sbmt
44
module Outbox
5-
VERSION = "6.9.0"
5+
VERSION = "6.10.0"
66
end
77
end

spec/interactors/sbmt/outbox/process_item_spec.rb

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
it "returns error" do
2525
expect(Sbmt::Outbox.error_tracker).to receive(:error)
2626
expect(Sbmt::Outbox.logger).to receive(:log_failure)
27-
.with(/Failed processing outbox item with error: not found/, backtrace: nil)
27+
.with(/Failed processing outbox item with error: not found/, stacktrace: nil)
2828
expect(result).not_to be_success
2929
expect(dummy_middleware).not_to have_received(:call)
3030
expect(result.failure).to eq :not_found
@@ -45,8 +45,9 @@
4545

4646
it "doesn't report error" do
4747
expect(Sbmt::Outbox.error_tracker).not_to receive(:error)
48-
expect(Sbmt::Outbox.logger).to receive(:log_failure)
48+
allow(Sbmt::Outbox.logger).to receive(:log_info)
4949
expect(result).not_to be_success
50+
expect(Sbmt::Outbox.logger).to have_received(:log_info).with("already processed")
5051
expect(dummy_middleware).not_to have_received(:call)
5152
expect(result.failure).to eq :already_processed
5253
end
@@ -200,7 +201,7 @@
200201
it "tracks error" do
201202
expect(Sbmt::Outbox.error_tracker).to receive(:error)
202203
expect(Sbmt::Outbox.logger).to receive(:log_failure)
203-
.with(/Failed processing outbox item with error: RuntimeError boom/, backtrace: kind_of(String))
204+
.with(/Failed processing outbox item with error: RuntimeError boom/, stacktrace: kind_of(String))
204205
expect(result.failure).to eq :transport_failure
205206
end
206207

@@ -211,6 +212,34 @@
211212
it "tracks Yabeda error counter" do
212213
expect { result }.to increment_yabeda_counter(Yabeda.outbox.error_counter).by(1)
213214
end
215+
216+
context "when error persisting fails" do
217+
before do
218+
allow_any_instance_of(OutboxItem).to receive(:failed!).and_raise("boom")
219+
end
220+
221+
it "returns error" do
222+
expect(result).to be_failure
223+
end
224+
225+
it "logs failure" do
226+
expect(Sbmt::Outbox.error_tracker).to receive(:error)
227+
allow(Sbmt::Outbox.logger).to receive(:log_failure)
228+
expect(result.failure).to eq :transport_failure
229+
expect(Sbmt::Outbox.logger)
230+
.to have_received(:log_failure)
231+
.with(/Could not persist status of failed outbox item due to error: RuntimeError boom/, stacktrace: kind_of(String))
232+
end
233+
234+
it "calls middleware" do
235+
result
236+
expect(dummy_middleware).to have_received(:call).with(outbox_item)
237+
end
238+
239+
it "tracks Yabeda error counter" do
240+
expect { result }.to increment_yabeda_counter(Yabeda.outbox.error_counter).by(1)
241+
end
242+
end
214243
end
215244

216245
context "when item processing returning failure" do

spec/lib/sbmt/outbox/v1/worker_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
end
140140

141141
expect(Sbmt::Outbox.logger).to receive(:log_error)
142-
.with(/test error/, hash_including(:backtrace))
142+
.with(/test error/, hash_including(:stacktrace))
143143
.and_call_original
144144

145145
worker.start

0 commit comments

Comments
 (0)