Class: RuboCop::Cop::DevDoc::Style::AvoidHeadResponse

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/dev_doc/style/avoid_head_response.rb

Overview

Avoid ‘head()` with error status codes in controllers.

## Rationale Using ‘head()` for error responses returns an empty body with no useful information for the client. Error handling should be delegated to Rails exceptions (e.g. `ActiveRecord::RecordNotFound`) or model validations instead, which give the client more context.

Success statuses like ‘:ok`, `:no_content`, and `:accepted` are legitimate uses of `head()` and are not flagged.

The set of flagged statuses is configurable via ‘FlaggedStatuses:`.

❌ Manually returns 404 with no body
def show
  @user = User.find_by(id: params[:id])
  head(:not_found) unless @user
end

✔️ Let Rails raise RecordNotFound — it renders the standard 404
def show
  @user = User.find(params[:id])
end

✔️ Success response — empty body is correct here
def destroy
  @resource.destroy!
  head :no_content
end

Examples:

# bad
head(:not_found)

# bad
head(:unprocessable_entity)

# good (success status — not flagged)
head(:no_content)

# good (success status — not flagged)
head(:ok)

# good (dynamic status — not flagged to avoid false positives)
head(status_code)

Constant Summary collapse

MSG =
'Avoid `head(%<status>s)` for error handling. ' \
'Delegate to Rails exceptions or model validations instead.'.freeze
RESTRICT_ON_SEND =
%i[head].freeze
DEFAULT_FLAGGED_STATUSES =
%w[
  not_found unprocessable_entity forbidden unauthorized
  bad_request conflict gone method_not_allowed
  404 422 403 401 400 409 410 405
].freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



62
63
64
65
66
67
68
69
70
# File 'lib/rubocop/cop/dev_doc/style/avoid_head_response.rb', line 62

def on_send(node)
  return unless node.receiver.nil?

  status_node = node.arguments.first
  return unless status_node
  return unless flagged_literal?(status_node)

  add_offense(node.loc.selector, message: format(MSG, status: status_display(status_node)))
end