diff options
Diffstat (limited to 'rubocop')
-rw-r--r-- | rubocop/cop/graphql/resource_not_available_error.rb | 47 | ||||
-rw-r--r-- | rubocop/node_pattern_helper.rb | 14 |
2 files changed, 61 insertions, 0 deletions
diff --git a/rubocop/cop/graphql/resource_not_available_error.rb b/rubocop/cop/graphql/resource_not_available_error.rb new file mode 100644 index 00000000000..d759e145008 --- /dev/null +++ b/rubocop/cop/graphql/resource_not_available_error.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require_relative '../../node_pattern_helper' + +module RuboCop + module Cop + module Graphql + # Encourages the use of `raise_resource_not_available_error!` method + # instead of `raise Gitlab::Graphql::Errors::ResourceNotAvailable`. + # + # @example + # + # # bad + # raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'message' + # + # # good + # raise_resource_not_available_error! 'message' + class ResourceNotAvailableError < Base + extend NodePatternHelper + extend AutoCorrector + + MSG = 'Prefer using `raise_resource_not_available_error!` instead.' + + EXCEPTION = 'Gitlab::Graphql::Errors::ResourceNotAvailable' + + RESTRICT_ON_SEND = %i[raise].freeze + + def_node_matcher :error, const_pattern(EXCEPTION) + + def_node_matcher :raise_error, <<~PATTERN + (send nil? :raise #error $...) + PATTERN + + def on_send(node) + raise_error(node) do |args| + add_offense(node) do |corrector| + replacement = +'raise_resource_not_available_error!' + replacement << " #{args.map(&:source).join(', ')}" if args.any? + + corrector.replace(node, replacement) + end + end + end + end + end + end +end diff --git a/rubocop/node_pattern_helper.rb b/rubocop/node_pattern_helper.rb new file mode 100644 index 00000000000..ecd4560763c --- /dev/null +++ b/rubocop/node_pattern_helper.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module RuboCop + module NodePatternHelper + # Returns a nested `(const ...)` node pattern for a full qualified +name+. + # + # @examples + # const_pattern 'Foo::Bar' # => (const (const {nil? cbase} :Foo) :Bar) + # const_pattern 'Foo::Bar', parent: ':Baz' # => (const (const :Baz :Foo) :Bar) + def const_pattern(name, parent: '{nil? cbase}') + name.split('::').inject(parent) { |memo, name_part| "(const #{memo} :#{name_part})" } + end + end +end |