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