renderやredirect_toを使っていないのにAbstractController::DoubleRenderError
ローカル環境や本番環境では問題ないのですが、staging環境でのみDoubleRenderError
が出ます。
エラーメッセージの最後にredirect_to(...) and return
とあるのですが、このアクション内にはredirect_to
もrender
もないため、別のところに問題があると推測しています。
サーバーが立ち上がらなくなったことがあり、それを復旧した際の処理の何かがおそらく引っかかっているのだと思います。
エラー全文
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".):
環境
- macOS High Sierra(バージョン10.13.6)
- ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin17]
- Rails 4.2.6
試したこと
以下のようにproduct_controllerのdownloadzipアクションにデバッグを追加してログを確認してみました。
# product_controller.rb
def downloadzip
@product = Product.find_by(id: params[:id])
download_cnts = DownloadLog.where(user_id: current_user.id).current_month.count
plan = current_user.enable_download_plan
logger.debug("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
return if download_cnts >= plan.download_limit
logger.debug("bbbbbbbbbbbbbbbbbbbbbbbbbbbb")
file_path = set_zip_url(@product)
logger.debug("cccccccccccccccccccccccccccccccc")
ActiveRecord::Base.transaction do
logger.debug("dddddddddddddddddddddddddddddddd")
file_download(file_path, "livesearch")
logger.debug("eeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
logger.debug(current_user)
logger.debug("ffffffffffffffffffffffffffffff")
logger.debug(@product)
logger.debug("ggggggggggggggggggggggggggggggggg")
DownloadLog.create(user_id: current_user.id, product_id: @product.id)
logger.debug("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")
end
end
staging.logでログを確認すると、
logger.debug("ggggggggggggggggggggggggggggggggg")
までは問題ないようですが、logger.debug("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")
でのデバッグがなく、DownloadLog.create(user_id: current_user.id, product_id: @product.id)
の部分でエラーが起きているようです。
# staging.log
D, [2019-01-10T03:13:33.310428 #9193] DEBUG -- : ggggggggggggggggggggggggggggggggg
D, [2019-01-10T03:13:33.315289 #9193] DEBUG -- : ESC[1mESC[36mProduct Load (0.3ms)ESC[0m ESC[1mSELECT `products`.* FROM `products` WHERE `products`.`id` = 67 LIMIT 1ESC[0m
D, [2019-01-10T03:13:33.316273 #9193] DEBUG -- : ESC[1mESC[35m (0.2ms)ESC[0m SELECT COUNT(*) FROM `download_logs` WHERE `download_logs`.`product_id` = 67
D, [2019-01-10T03:13:35.683743 #9193] DEBUG -- : ESC[1mESC[36m (0.1ms)ESC[0m ESC[1mROLLBACKESC[0m
E, [2019-01-10T03:13:35.684035 #9193] ERROR -- : Rendering 500 with exception: undefined method `[]' for nil:NilClass
I, [2019-01-10T03:13:35.947113 #9193] INFO -- : Completed 500 Internal Server Error in 3226ms (ActiveRecord: 8.6ms)
F, [2019-01-10T03:13:36.198009 #9193] FATAL -- :
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/application_controller.rb:51:in `block (2 levels) in handle_500'
app/controllers/application_controller.rb:49:in `handle_500'
Rendering 500 with exception: undefined method ``[]' for nil:NilClass
とありますが、[]を記述していないので、なぜこのエラーができているのかわかりません。model/download_log.rbにもapplication_controller.rbのhandle_500
にも記述はありませんでした。
# model/download_log.rb
class DownloadLog < ActiveRecord::Base
belongs_to :user, foreign_key: 'user_id'
belongs_to :product, foreign_key: 'product_id'
scope :current_month, -> { where(created_at: Time.current.beginning_of_month..Time.current.end_of_month) }
before_save :set_dl_cnt_to_product
def set_dl_cnt_to_product
self.product.update(dl_cnt: DownloadLog.where(product_id: self.product.id).count + 1)
end
end
# application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
rescue_from Exception, with: :handle_500 unless Rails.env.development?
def handle_500(exception = nil)
logger.error "Rendering 500 with exception: #{exception.message}" if exception
ExceptionNotifier.notify_exception(exception, env: request.env, data: {message: "error"})
respond_to do |format|
format.html {
return render template: 'errors/error_500', status: 500, layout: false, content_type: 'text/html'
}
format.all {
return head :internal_server_error
}
end
end
end
また、application_controller.rbのhandle_505内の
return render template: 'errors/error_500', status: 500, layout: false, content_type:
の一行を
render template: 'errors/error_500', status: 500, layout: false, content_type: and return
と変えてみましたが、エラーメッセージに変化はありませんでした。
実現したいこと
staging環境でのみAbstractController::DoubleRenderError
が起こる原因を究明したいです。
ご教示いただけることがあれば、何卒よろしくお願いいたします。