Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new
Lint/DuplicateRescueException
cop
- Loading branch information
Showing
7 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# frozen_string_literal: true | ||
|
||
module RuboCop | ||
module Cop | ||
module Lint | ||
# This cop checks that there are no repeated exceptions | ||
# used in 'rescue' expressions. | ||
# | ||
# @example | ||
# # bad | ||
# begin | ||
# something | ||
# rescue FirstException | ||
# handle_exception | ||
# rescue FirstException | ||
# handle_other_exception | ||
# end | ||
# | ||
# # good | ||
# begin | ||
# something | ||
# rescue FirstException | ||
# handle_exception | ||
# rescue SecondException | ||
# handle_other_exception | ||
# end | ||
# | ||
class DuplicateRescueException < Base | ||
include RescueNode | ||
|
||
MSG = 'Duplicate `rescue` exception detected.' | ||
|
||
def on_rescue(node) | ||
return if rescue_modifier?(node) | ||
|
||
_body, *resbodies, _else = *node | ||
|
||
resbodies.each_with_object(Set.new) do |resbody, previous| | ||
rescued_exceptions = rescued_exceptions(resbody) | ||
|
||
rescued_exceptions.each do |exception| | ||
add_offense(exception) unless previous.add?(exception) | ||
end | ||
end | ||
end | ||
|
||
private | ||
|
||
def rescued_exceptions(resbody) | ||
rescue_group, = *resbody | ||
if rescue_group | ||
rescue_group.values | ||
else | ||
[] | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe RuboCop::Cop::Lint::DuplicateRescueException do | ||
subject(:cop) { described_class.new } | ||
|
||
it 'registers an offense when duplicate exception exists' do | ||
expect_offense(<<~RUBY) | ||
begin | ||
something | ||
rescue FirstError | ||
rescue SecondError, FirstError | ||
^^^^^^^^^^ Duplicate `rescue` exception detected. | ||
end | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when duplicate exception splat exists' do | ||
expect_offense(<<~RUBY) | ||
begin | ||
something | ||
rescue *ERRORS | ||
rescue SecondError, *ERRORS | ||
^^^^^^^ Duplicate `rescue` exception detected. | ||
end | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when multiple duplicate exceptions exist' do | ||
expect_offense(<<~RUBY) | ||
begin | ||
something | ||
rescue FirstError | ||
rescue SecondError | ||
rescue FirstError | ||
^^^^^^^^^^ Duplicate `rescue` exception detected. | ||
rescue SecondError | ||
^^^^^^^^^^^ Duplicate `rescue` exception detected. | ||
end | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when duplicate exception exists within rescues with `else` branch' do | ||
expect_offense(<<~RUBY) | ||
begin | ||
something | ||
rescue FirstError | ||
rescue SecondError, FirstError | ||
^^^^^^^^^^ Duplicate `rescue` exception detected. | ||
else | ||
end | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when duplicate exception exists within rescues with empty `rescue` branch' do | ||
expect_offense(<<~RUBY) | ||
begin | ||
something | ||
rescue FirstError | ||
rescue SecondError, FirstError | ||
^^^^^^^^^^ Duplicate `rescue` exception detected. | ||
rescue | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when there are no duplicate exceptions' do | ||
expect_no_offenses(<<~RUBY) | ||
begin | ||
something | ||
rescue FirstError | ||
rescue SecondError | ||
end | ||
RUBY | ||
end | ||
end |