This project is archived and is in readonly mode.

#5773 ✓duplicate
Simone Carletti

ActionController crashes when trying to render head 406 with caches_action

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

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

Comments and changes to this ticket

  • Simone Carletti

    Simone Carletti October 8th, 2010 @ 09:39 PM

    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.

  • José Valim

    José Valim October 8th, 2010 @ 11:21 PM

    • Importance changed from “” to “Low”

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

  • Simone Carletti

    Simone Carletti October 9th, 2010 @ 11:56 AM

    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.

  • David Trasbo

    David Trasbo October 9th, 2010 @ 12:06 PM

    • 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
    
  • Santiago Pastorino

    Santiago Pastorino February 2nd, 2011 @ 04:58 PM

    • 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.

  • Santiago Pastorino

    Santiago Pastorino February 2nd, 2011 @ 04:58 PM

    • State changed from “open” to “stale”
  • Wayne See

    Wayne See February 12th, 2011 @ 03:39 PM

    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.

  • Wayne See

    Wayne See February 12th, 2011 @ 03:47 PM

    • State changed from “stale” to “open”

    [state:open]

  • Wayne See

    Wayne See March 1st, 2011 @ 03:09 PM

    • State changed from “open” to “duplicate”

    Duplicate of #6480

    [state:duplicate]

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Attachments

Referenced by

Pages