Skip to content

Commit

Permalink
Add new Naming/RescuedExceptionsVariableName cop
Browse files Browse the repository at this point in the history
Use a consistent naming of the rescued exceptions variable. Prevent
naming rescued `Exception` variable other than the preferred configured
one.

The default naming configuration is "ex".
  • Loading branch information
AdrienSdy authored and bbatsov committed Apr 4, 2019
1 parent b05bb15 commit f0959e8
Show file tree
Hide file tree
Showing 19 changed files with 298 additions and 38 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* [#5184](https://github.com/rubocop-hq/rubocop/issues/5184): Add new multiline element line break cops. ([@maxh][])
* Add new cop `Rails/ActiveRecordOverride` that checks for overriding Active Record methods instead of using callbacks. ([@elebow][])
* Add new cop `Rails/RedundantAllowNil` that checks for cases when `allow_blank` makes `allow_nil` unnecessary in model validations. ([@elebow][])
* Add new `Naming/RescuedExceptionsVariableName` cop. ([@AdrienSldy][])

### Bug fixes

Expand Down Expand Up @@ -3730,6 +3731,7 @@
[@sue445]: https://github.com/sue445
[@zverok]: https://github.com/zverok
[@backus]: https://github.com/backus
[@AdrienSldy]: https://github.com/adriensldy
[@pat]: https://github.com/pat
[@sinsoku]: https://github.com/sinsoku
[@nodo]: https://github.com/nodo
Expand Down
6 changes: 3 additions & 3 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ require 'bundler'
require 'bundler/gem_tasks'
begin
Bundler.setup(:default, :development)
rescue Bundler::BundlerError => e
warn e.message
rescue Bundler::BundlerError => ex
warn ex.message
warn 'Run `bundle install` to install missing gems'
exit e.status_code
exit ex.status_code
end
require 'rake'
require 'rubocop/rake_task'
Expand Down
6 changes: 6 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1935,6 +1935,12 @@ Naming/PredicateName:
Exclude:
- 'spec/**/*'

Naming/RescuedExceptionsVariableName:
Description: 'Use consistent rescued exceptions variables naming.'
Enabled: true
VersionAdded: '0.67'
PreferredName: ex

Naming/UncommunicativeBlockParamName:
Description: >-
Checks for block parameter names that contain capital letters,
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@
require_relative 'rubocop/cop/naming/method_name'
require_relative 'rubocop/cop/naming/binary_operator_parameter_name'
require_relative 'rubocop/cop/naming/predicate_name'
require_relative 'rubocop/cop/naming/rescued_exceptions_variable_name'
require_relative 'rubocop/cop/naming/uncommunicative_block_param_name'
require_relative 'rubocop/cop/naming/uncommunicative_method_param_name'
require_relative 'rubocop/cop/naming/variable_name'
Expand Down
20 changes: 11 additions & 9 deletions lib/rubocop/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,23 @@ def run(args = ARGV)
act_on_options
apply_default_formatter
execute_runners(paths)
rescue ConfigNotFoundError, IncorrectCopNameError, OptionArgumentError => e
warn e.message
rescue ConfigNotFoundError,
IncorrectCopNameError,
OptionArgumentError => ex
warn ex.message
STATUS_ERROR
rescue RuboCop::Error => e
warn Rainbow("Error: #{e.message}").red
rescue RuboCop::Error => ex
warn Rainbow("Error: #{ex.message}").red
STATUS_ERROR
rescue Finished
STATUS_SUCCESS
rescue OptionParser::InvalidOption => e
warn e.message
rescue OptionParser::InvalidOption => ex
warn ex.message
warn 'For usage information, use --help'
STATUS_ERROR
rescue StandardError, SyntaxError, LoadError => e
warn e.message
warn e.backtrace
rescue StandardError, SyntaxError, LoadError => ex
warn ex.message
warn ex.backtrace
STATUS_ERROR
end
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/config_loader_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ def transform(config)
def gem_config_path(gem_name, relative_config_path)
spec = Gem::Specification.find_by_name(gem_name)
File.join(spec.gem_dir, relative_config_path)
rescue Gem::LoadError => e
rescue Gem::LoadError => ex
raise Gem::LoadError,
"Unable to find gem #{gem_name}; is the gem installed? #{e}"
"Unable to find gem #{gem_name}; is the gem installed? #{ex}"
end
end
end
6 changes: 3 additions & 3 deletions lib/rubocop/cop/commissioner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@ def invoke_custom_processing(cops_or_forces, processed_source)
# cops' `#investigate` methods.
def with_cop_error_handling(cop, node = nil)
yield
rescue StandardError => e
raise e if @options[:raise_error]
rescue StandardError => ex
raise ex if @options[:raise_error]

if node
line = node.first_line
column = node.loc.column
end
error = CopError.new(e, line, column)
error = CopError.new(ex, line, column)
@errors[cop] << error
end
end
Expand Down
76 changes: 76 additions & 0 deletions lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Naming
# This cop makes sure that rescued exceptions variables are named as
# expected.
#
# The `PreferredName` config option takes a `String`. It represents
# the required name of the variable. Its default is `e`.
#
# @example PreferredName: e (default)
# # bad
# begin
# # do something
# rescue MyException => exc
# # do something
# end
#
# # good
# begin
# # do something
# rescue MyException => e
# # do something
# end
#
# @example PreferredName: exception
# # bad
# begin
# # do something
# rescue MyException => e
# # do something
# end
#
# # good
# begin
# # do something
# rescue MyException => ex
# # do something
# end
#
class RescuedExceptionsVariableName < Cop
MSG = 'Use `%<preferred>s` instead of `%<bad>s`.'.freeze

def on_resbody(node)
exception_type, @exception_name = *node
return unless exception_type || @exception_name

@exception_name ||= exception_type.children.first
return if @exception_name.const_type? ||
variable_name == preferred_name

add_offense(node, location: location)
end

private

def preferred_name
@preferred_name ||= cop_config.fetch('PreferredName', 'e')
end

def variable_name
@variable_name ||= location.source
end

def location
@location ||= @exception_name.loc.expression
end

def message(_node = nil)
format(MSG, preferred: preferred_name, bad: variable_name)
end
end
end
end
end
6 changes: 3 additions & 3 deletions lib/rubocop/path_util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ def match_path?(pattern, path)
when Regexp
begin
path =~ pattern
rescue ArgumentError => e
return false if e.message.start_with?('invalid byte sequence')
rescue ArgumentError => ex
return false if ex.message.start_with?('invalid byte sequence')

raise e
raise exception
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/processed_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ def parse(source, ruby_version)

begin
@buffer.source = source
rescue EncodingError => error
@parser_error = error
rescue EncodingError => ex
@parser_error = ex
return
end

Expand Down
10 changes: 6 additions & 4 deletions lib/rubocop/remote_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ def request(uri = @uri, limit = 10, &block)
generate_request(uri) do |request|
begin
handle_response(http.request(request), limit, &block)
rescue SocketError => err
handle_response(err, limit, &block)
rescue SocketError => ex
handle_response(ex, limit, &block)
end
end
end
Expand All @@ -72,8 +72,10 @@ def handle_response(response, limit, &block)
else
begin
response.error!
rescue StandardError => e
raise e, "#{e.message} while downloading remote config file #{uri}"
rescue StandardError => ex
message = "#{ex.message} while downloading remote config"\
" file #{uri}"
raise ex, message
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/result_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ def save(offenses)

begin
FileUtils.mkdir_p(dir)
rescue Errno::EACCES => e
rescue Errno::EACCES => ex
warn "Couldn't create cache directory. Continuing without cache."\
"\n #{e.message}"
"\n #{ex.message}"
return
end

Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ def process_file(file)
end
formatter_set.file_finished(file, offenses)
offenses
rescue InfiniteCorrectionLoop => e
formatter_set.file_finished(file, e.offenses.compact.sort.freeze)
rescue InfiniteCorrectionLoop => ex
formatter_set.file_finished(file, ex.offenses.compact.sort.freeze)
raise
end

Expand Down
9 changes: 7 additions & 2 deletions lib/rubocop/target_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,13 @@ def ruby_executable?(file)

first_line = File.open(file, &:readline)
!(first_line =~ /#!.*(#{ruby_interpreters(file).join('|')})/).nil?
rescue EOFError, ArgumentError => e
warn "Unprocessable file #{file}: #{e.class}, #{e.message}" if debug?
rescue EOFError, ArgumentError => ex
if debug?
warn(
"Unprocessable file #{file}: #{ex.class}, #{ex.message}"
)
end

false
end

Expand Down
1 change: 1 addition & 0 deletions manual/cops.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ In the following section you find all available cops:
* [Naming/MemoizedInstanceVariableName](cops_naming.md#namingmemoizedinstancevariablename)
* [Naming/MethodName](cops_naming.md#namingmethodname)
* [Naming/PredicateName](cops_naming.md#namingpredicatename)
* [Naming/RescuedExceptionsVariableName](cops_naming.md#namingrescuedexceptionsvariablename)
* [Naming/UncommunicativeBlockParamName](cops_naming.md#naminguncommunicativeblockparamname)
* [Naming/UncommunicativeMethodParamName](cops_naming.md#naminguncommunicativemethodparamname)
* [Naming/VariableName](cops_naming.md#namingvariablename)
Expand Down
57 changes: 56 additions & 1 deletion manual/cops_naming.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ Name | Default value | Configurable values
--- | --- | ---
Exclude | `[]` | Array
ExpectMatchingDefinition | `false` | Boolean
Regex | `<none>` |
Regex | `<none>` |
IgnoreExecutableScripts | `true` | Boolean
AllowedAcronyms | `CLI`, `DSL`, `ACL`, `API`, `ASCII`, `CPU`, `CSS`, `DNS`, `EOF`, `GUID`, `HTML`, `HTTP`, `HTTPS`, `ID`, `IP`, `JSON`, `LHS`, `QPS`, `RAM`, `RHS`, `RPC`, `SLA`, `SMTP`, `SQL`, `SSH`, `TCP`, `TLS`, `TTL`, `UDP`, `UI`, `UID`, `UUID`, `URI`, `URL`, `UTF8`, `VM`, `XML`, `XMPP`, `XSRF`, `XSS` | Array
Expand Down Expand Up @@ -477,6 +477,61 @@ Exclude | `spec/**/*` | Array
* [https://github.com/rubocop-hq/ruby-style-guide#bool-methods-qmark](https://github.com/rubocop-hq/ruby-style-guide#bool-methods-qmark)
## Naming/RescuedExceptionsVariableName
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
--- | --- | --- | --- | ---
Enabled | Yes | No | 0.67 | -
This cop makes sure that rescued exceptions variables are named as
expected.
The `PreferredName` config option takes a `String`. It represents
the required name of the variable. Its default is `e`.
### Examples
#### PreferredName: e (default)
```ruby
# bad
begin
# do something
rescue MyException => exc
# do something
end

# good
begin
# do something
rescue MyException => e
# do something
end
```
#### PreferredName: exception
```ruby
# bad
begin
# do something
rescue MyException => e
# do something
end

# good
begin
# do something
rescue MyException => ex
# do something
end
```
### Configurable attributes
Name | Default value | Configurable values
--- | --- | ---
PreferredName | `ex` | String
## Naming/UncommunicativeBlockParamName
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
Expand Down
6 changes: 3 additions & 3 deletions spec/rubocop/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1602,9 +1602,9 @@ def method(foo, bar, qux, fred, arg5, f) end #{'#' * 45}
it 'shows an error if the input file cannot be found' do
begin
cli.run(%w[/tmp/not_a_file])
rescue SystemExit => e
expect(e.status).to eq(1)
expect(e.message)
rescue SystemExit => ex
expect(ex.status).to eq(1)
expect(ex.message)
.to eq 'rubocop: No such file or directory -- /tmp/not_a_file'
end
end
Expand Down
Loading

0 comments on commit f0959e8

Please sign in to comment.