Remy Wang
Remy Wang

Reputation: 793

Rails - AbstractController::DoubleRenderError in my controller

This is my controller

class Api::V1::WebhooksController < ApplicationController
  include Api::V1::WebhookHelper
  include Api::V1::LogHelper

  skip_before_action :verify_authenticity_token
  after_action :handle_wehbook

  # Schedule plan
  def schedule_plan
    add_log(status: "webhook", message: "New Plan is scheduled.")
  end

  def handle_wehbook
    if webhook_verified?
      webhook_verified!
      render status: 200, json: { error: 'webhook is verified.' }
    else
      webhook_verified!(verified: false)
      render status: 500, json: { error: 'webhook is not verified.' }
    end
  end
end

This is Webhook Helper.

I am sure in WebhookHelper, it never redirects or renders anything.

require 'openssl'
require 'base64'

module Api::V1::WebhookHelper
  include Api::V1::LogHelper

  def webhook_verified?
    digest = OpenSSL::Digest.new('sha256')
    hmac = OpenSSL::HMAC.digest(digest, secret, request.body.read)
    hash = Base64.encode64(hmac).strip

    hash == signature
  end

  def secret
    ENV["API_KEY"]
  end

  def signature
    request.headers["HTTP_X_SIGNATURE"] 
  end

  def webhook_verified!(verified: true)
    if verified
      add_log(status: "webhook", message: "Webhook is verified.") # only puts log
    else
      add_log(status: "webhook", type: "warning", message: "Webhook is not verified.") # only puts log
    end
  end
end

I am getting this issue.

AbstractController::DoubleRenderError (Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".):

app/controllers/api/v1/webhooks_controller.rb:31:in `handle_wehbook'

I am not sure I am calling render or redirect multiple times in my action. Anyone can help me?

Upvotes: 0

Views: 196

Answers (1)

Vasfed
Vasfed

Reputation: 18464

Your handle_wehbook function is an after_action, it runs after some other action.

The latter has already rendered something (it may be an rails error or a redirect) thus the double render

Upvotes: 1

Related Questions