Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

ActionController crashes when trying to render head 406 with caches_action

#5773

To reproduce the bug:

  1. create an action and return head 406
  2. add caches_action for that specific action
  3. enable action caching

Example

class MainController < ActionController::Base
  caches_action :index
  def index
    head 406
  end
end

Here's the backtrace


[ pid=1515 thr=2148381100 file=utils.rb:176 time=2010-10-08 22:15:38.714 ]: *** Exception NoMethodError in application (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each) (process 1515, thread #<Thread:0x1001b6358>):
    from /Users/weppos/.rvm/gems/ruby-1.8.7-p249/gems/actionpack-3.0.0/lib/action_dispatch/http/response.rb:155:in `each'
    from /Users/weppos/.rvm/gems/ruby-1.8.7-p249/gems/actionpack-3.0.0/lib/action_dispatch/http/response.rb:102:in `body'
    from /Users/weppos/.rvm/gems/ruby-1.8.7-p249/gems/rack-1.2.1/lib/rack/response.rb:102:in `close'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/rack/request_handler.rb:136:in `process_request'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_request_handler.rb:513:in `accept_and_process_next_request'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_request_handler.rb:274:in `main_loop'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/rack/application_spawner.rb:205:in `start_request_handler'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/rack/application_spawner.rb:170:in `send'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/rack/application_spawner.rb:170:in `handle_spawn_application'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/utils.rb:479:in `safe_fork'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/rack/application_spawner.rb:165:in `handle_spawn_application'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:357:in `__send__'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:357:in `server_main_loop'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:206:in `start_synchronously'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:180:in `start'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/rack/application_spawner.rb:128:in `start'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/spawn_manager.rb:253:in `spawn_rack_application'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_server_collection.rb:132:in `lookup_or_add'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/spawn_manager.rb:246:in `spawn_rack_application'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_server_collection.rb:82:in `synchronize'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_server_collection.rb:79:in `synchronize'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/spawn_manager.rb:244:in `spawn_rack_application'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/spawn_manager.rb:137:in `spawn_application'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/spawn_manager.rb:275:in `handle_spawn_application'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:357:in `__send__'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:357:in `server_main_loop'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:206:in `start_synchronously'
    from /Users/weppos/.passenger/standalone/3.0.0.pre4-x86_64-ruby1.8.7-macosx-10.6/support/helper-scripts/passenger-spawn-server:99

Reported by Simone Carletti · October 8th, 2010 @ 09:33 PM

State: duplicate
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Simone Carletti
    Simone Carletti

    I investigate the issue and here's what I discovered.

    When the cache doesn't exist, read_fragment returns nil and body is set to nil.

    When the content of the unless condition is executed, _safe_fragment returns nil because the caching_allowed? check evaluates to false (remember, the status code is 406).

    render_to_string is skipped because head doesn't want any layout and a nil body is passed to rack, which expects body to be a String.

    October 8th, 2010 @ 09:39 PM

  2. José Valim
    José Valim
    • Importance changed from to Low

    Can you provide a test case to Rails suite? Or even a patch with tests fixing the issue?

    October 8th, 2010 @ 11:21 PM

  3. Simone Carletti
    Simone Carletti

    I tried to reproduce the error without success. I can't understand why but the test doesn't fail.
    I need to verify where edge Rails fixes the issue.

    October 9th, 2010 @ 11:56 AM

  4. David Trasbo
    David Trasbo
    • State changed from new to open

    Confirmed on edge Rails:

    $ script/rails g controller foos index
    ...
    

    Controller:

    class FoosController < ApplicationController
      caches_action :index
    
      def index
        head 406
      end
    end
    

    Routes:

    Ticket5773::Application.routes.draw do
      resources :foos
    end
    

    Request to http://localhost:3000/foos results in Internal Server Error and log displays the following:

    Started GET "/foos" for 127.0.0.1 at 2010-10-09 13:02:28 +0200
      Processing by FoosController#index as HTML
    Read fragment views/localhost:3000/foos (0.1ms)
    Completed 406 Not Acceptable in 3ms
    [2010-10-09 13:02:28] ERROR NoMethodError: You have a nil object when you didn't expect it!
    You might have expected an instance of Array.
    The error occurred while evaluating nil.each
        /Users/dtrasbo/.rvm/gems/ruby-1.9.2-p0@edge_rails_app/bundler/gems/rails-b439c1451642/actionpack/lib/action_dispatch/http/response.rb:153:in `each'
        ...
    cache: [GET /favicon.ico] miss, store
    

    October 9th, 2010 @ 12:06 PM

  5. Santiago Pastorino
    Santiago Pastorino
    • Tag changed from rails 3.0.0, actioncontroller, caches_action, caching to rails 300, actioncontroller, caches_action, caching

    This issue has been automatically marked as stale because it has not been commented on for at least three months.

    The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.

    Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.

    February 2nd, 2011 @ 04:58 PM

  6. Santiago Pastorino
    Santiago Pastorino
    • State changed from open to stale

    February 2nd, 2011 @ 04:58 PM

  7. Wayne See
    Wayne See

    I've encountered this in production and as Simone pointed out, rendering a non-200 http status code response in an action that is cached using caches_action will cause rack to throw an exception. As Simone said earlier, this is because the response body is set to nil, but I'm not sure if rack should be able to handle a nil response body or action caching should not set it to nil.

    I've been using the attached patch in production to get rid of this error. Also included a test checking for nil response body.

    February 12th, 2011 @ 03:39 PM

  8. Wayne See
    Wayne See
    • State changed from stale to open

    [state:open]

    February 12th, 2011 @ 03:47 PM

  9. Wayne See