From d9ec02de75d95337e7dc2a8f876ba8a4874276c1 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 17 Mar 2022 16:48:16 +0900 Subject: [PATCH] [Fix #669] Fix a false positive for `Rails/TransactionExitStatement` Fixes #669. This PR fixes a false positive for `Rails/TransactionExitStatement` when `return` is used in `rescue`. --- ...alse_positive_for_rails_transaction_exit_statement.md | 1 + lib/rubocop/cop/rails/transaction_exit_statement.rb | 8 +++++++- .../rubocop/cop/rails/transaction_exit_statement_spec.rb | 9 +++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_false_positive_for_rails_transaction_exit_statement.md diff --git a/changelog/fix_false_positive_for_rails_transaction_exit_statement.md b/changelog/fix_false_positive_for_rails_transaction_exit_statement.md new file mode 100644 index 0000000000..e5cd39d2c4 --- /dev/null +++ b/changelog/fix_false_positive_for_rails_transaction_exit_statement.md @@ -0,0 +1 @@ +* [#669](https://github.com/rubocop/rubocop-rails/issues/669): Fix a false positive for `Rails/TransactionExitStatement` when `return` is used in `rescue`. ([@koic][]) diff --git a/lib/rubocop/cop/rails/transaction_exit_statement.rb b/lib/rubocop/cop/rails/transaction_exit_statement.rb index d2ec6c6ed0..373d9403d9 100644 --- a/lib/rubocop/cop/rails/transaction_exit_statement.rb +++ b/lib/rubocop/cop/rails/transaction_exit_statement.rb @@ -58,7 +58,7 @@ def on_send(node) return unless parent.block_type? && parent.body exit_statements(parent.body).each do |statement_node| - next if statement_node.break_type? && nested_block?(statement_node) + next if in_rescue?(statement_node) || nested_block?(statement_node) statement = statement(statement_node) message = format(MSG, statement: statement) @@ -79,7 +79,13 @@ def statement(statement_node) end end + def in_rescue?(statement_node) + statement_node.ancestors.find(&:rescue_type?) + end + def nested_block?(statement_node) + return false unless statement_node.break_type? + !statement_node.ancestors.find(&:block_type?).method?(:transaction) end end diff --git a/spec/rubocop/cop/rails/transaction_exit_statement_spec.rb b/spec/rubocop/cop/rails/transaction_exit_statement_spec.rb index c9212f2d4e..953e19a2d2 100644 --- a/spec/rubocop/cop/rails/transaction_exit_statement_spec.rb +++ b/spec/rubocop/cop/rails/transaction_exit_statement_spec.rb @@ -76,6 +76,15 @@ RUBY end + it 'does not register an offense when `return` is used in `rescue`' do + expect_no_offenses(<<~RUBY) + ApplicationRecord.transaction do + rescue + return do_something + end + RUBY + end + it 'does not register an offense when transaction block is empty' do expect_no_offenses(<<~RUBY) ApplicationRecord.transaction do