undefined method `bytesize' in JSON response #1730

Closed
tanordheim opened this Issue Jun 16, 2011 · 7 comments

Comments

Projects
None yet
4 participants

Hello.

I'm doing some testing of Rails3.1 here, specifically the RC4 version, and I'm having some trouble with the responses from a RESTful action (in my case, a create action) using a :js format.

As I've understood it, using respond_to :js and respond_with, an XHR-request to a create/update action where the model validation fails, should return a "422 Unprocessable Entity" header, and a JSON body that highlights the details of the validation error, for instance:

{ name: ["Can't be blank"] }

It does, as expected, return the correct header, but an error is being raised from within the ContentLength rack middleware:

[2011-06-16 14:11:34] ERROR NoMethodError: undefined method `bytesize' for :name:Symbol
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/rack-1.3.0/lib/rack/utils.rb:250:in `bytesize'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/railties-3.1.0.rc4/lib/rails/rack/content_length.rb:28:in `block in call'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/rack-1.3.0/lib/rack/lock.rb:7:in `block in each'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:135:in `block (2 levels) in each'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:135:in `each'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:135:in `block in each'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:134:in `each_key'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:134:in `each'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/actionpack-3.1.0.rc4/lib/action_dispatch/http/response.rb:43:in `each'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/activerecord-3.1.0.rc4/lib/active_record/query_cache.rb:37:in `each'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/activerecord-3.1.0.rc4/lib/active_record/connection_adapters/abstract/connection_pool.rb:429:in `each'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/rack-1.3.0/lib/rack/lock.rb:7:in `each'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/railties-3.1.0.rc4/lib/rails/rack/content_length.rb:26:in `call'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/railties-3.1.0.rc4/lib/rails/rack/log_tailer.rb:14:in `call'
    /Users/Trond/.rvm/gems/ruby-1.9.2-p180@bytesize_test/gems/rack-1.3.0/lib/rack/handler/webrick.rb:59:in `service'
    /Users/Trond/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
    /Users/Trond/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
    /Users/Trond/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'

I've created a minimal test application highlighting the issue at https://github.com/tanordheim/rails_3_1_bytesize_error_test. This is tested on Ruby1.9.2-p180 using Rails 3.1.0.rc4 and master with a blank gemset.

I've included a simple test in this project as well (found in test/functional/tests_controller_test.rb) to highlight the problem, but the tests actually pass - though the response body from the JS create request only contains the string "name", with no information as to how the validation failed. However, by starting up the server and testing the controllers via a browser (in my case Firefox 4.0.1), I get the following error when submitting the form without filling out the text field:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
  <HEAD><TITLE>Internal Server Error</TITLE></HEAD>
  <BODY>
    <H1>Internal Server Error</H1>
    undefined method `bytesize' for :name:Symbol
    <HR>
    <ADDRESS>
     WEBrick/1.3.1 (Ruby/1.9.2/2011-02-18) at
     localhost:3000
    </ADDRESS>
  </BODY>
</HTML>

I apologize if this isn't supposed to work the way I imagined, but in either case having a request end up in an error seems wrong. I'll gladly assist in fixing the issue, but I'm not familiar enough with the Rails code to know where to start digging. If anyone has any pointers or ideas as to what might happen here, I can attempt to write some tests for Rails to try and reproduce the issue there.

Actually, I just tested the Rails application I linked to in the previous post with Ruby 1.8.7-p302 and a clean gemset, the error raised has now changed slightly:

[2011-06-16 14:19:47] ERROR NoMethodError: undefined method `bytesize' for [:name, "can't be blank"]:Array
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/rack-1.3.0/lib/rack/utils.rb:250:in `bytesize'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/railties-3.1.0.rc4/lib/rails/rack/content_length.rb:28:in `call'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/rack-1.3.0/lib/rack/lock.rb:7:in `each'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:135:in `each'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:135:in `each'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/activesupport-3.1.0.rc4/lib/active_support/ordered_hash.rb:145:in `each_key'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/activesupport-3.1.0.rc4/lib/active_support/ordered_hash.rb:145:in `each'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/activesupport-3.1.0.rc4/lib/active_support/ordered_hash.rb:145:in `each_key'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:134:in `each'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/actionpack-3.1.0.rc4/lib/action_dispatch/http/response.rb:43:in `__send__'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/actionpack-3.1.0.rc4/lib/action_dispatch/http/response.rb:43:in `each'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/activerecord-3.1.0.rc4/lib/active_record/query_cache.rb:37:in `each'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/activerecord-3.1.0.rc4/lib/active_record/connection_adapters/abstract/connection_pool.rb:429:in `each'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/rack-1.3.0/lib/rack/lock.rb:7:in `each'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/railties-3.1.0.rc4/lib/rails/rack/content_length.rb:26:in `call'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/railties-3.1.0.rc4/lib/rails/rack/log_tailer.rb:14:in `call'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/rack-1.3.0/lib/rack/handler/webrick.rb:59:in `service'
    /Users/Trond/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
    /Users/Trond/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
    /Users/Trond/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
    /Users/Trond/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/webrick/server.rb:162:in `start'
    /Users/Trond/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
    /Users/Trond/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/webrick/server.rb:95:in `start'
    /Users/Trond/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/webrick/server.rb:92:in `each'
    /Users/Trond/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/webrick/server.rb:92:in `start'
    /Users/Trond/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/webrick/server.rb:23:in `start'
    /Users/Trond/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/webrick/server.rb:82:in `start'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/rack-1.3.0/lib/rack/handler/webrick.rb:13:in `run'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/rack-1.3.0/lib/rack/server.rb:265:in `start'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/railties-3.1.0.rc4/lib/rails/commands/server.rb:70:in `start'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/railties-3.1.0.rc4/lib/rails/commands.rb:54
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/railties-3.1.0.rc4/lib/rails/commands.rb:49:in `tap'
    /Users/Trond/.rvm/gems/ruby-1.8.7-p302@bytesize_test/gems/railties-3.1.0.rc4/lib/rails/commands.rb:49
    script/rails:6:in `require'
    script/rails:6

As mentioned in the previous post, I was a bit puzzled as to why the response body only contained "name", and not some kind of JSON response describing the error in more detail. With Ruby1.8.7 it actually seems to add this information to the response body.

dbkbali commented Jul 6, 2011

I am getting this error as well and have a custom validation. I am using Inherited resources and it also occurs when sending a form by Ajax, Here are relevant parts of my code and the console response and gemfile. As I am a newbie will try and debug and find out why this is happening

#app/models/country.rb
class Country
include Mongoid::Document
include Mongoid::I18n
include Mongoid::Slug
include Location

has_many :regions, index: true
has_many :places, index: true

index :name, unique: true

slug :name do |doc|
doc.name_translations["en"]
end

attr_accessible :name, :guide_title, :guide_content, :guide_source, :location, :zoom, :areas,
:name_translations, :guide_title_translations, :guide_content_translations
accepts_nested_attributes_for :name, :guide_title, :guide_content

validates_default_locale :name
validates_with EnglishNameUnique
end

#app/admin/countries_controller.rb

module Admin
class CountriesController < LocationsController
respond_to :html
respond_to :js

def create
   create! do |success, failure|
     failure.js {render :error_message}
     success.js do
       @countries = Country.asc("slug").to_a
       @countries = @countries.paginate
     end
   end
 end

 def update
   old_slug = @country.slug
   update! do |success, failure|
     failure.js {render :error_message}
     success.js do
       #@activity.reload
       render :update, :locals => {:old_slug => old_slug}
     end
   end
 end

end
end

#log
Started GET "/admin/countries/new?locale=en" for 127.0.0.1 at 2011-07-06 16:44:05 +0800
Processing by Admin::CountriesController#new as JS
Parameters: {"locale"=>"en"}
MONGODB what2do_asia_development['users'].find({:_id=>BSON::ObjectId('4e13e3499a4b7c395b000001')})
default_url_options is passed options: {}
Rendered application/_error_messages.html.haml (0.1ms)
Rendered admin/locations/_basic_info.html.haml (260.6ms)
Rendered admin/locations/_map.html.haml (0.1ms)
Rendered admin/locations/_geodata.haml (10.4ms)
Rendered admin/locations/_form.html.haml (406.2ms)
Rendered admin/countries/new.js.haml (418.3ms)
Completed 200 OK in 449ms (Views: 432.4ms | Mongo: 0.4ms)
[2011-07-06 16:44:17] ERROR NoMethodError: undefined method bytesize' for :name:Symbol /Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/rack-1.3.0/lib/rack/utils.rb:250:inbytesize'
/Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/railties-3.1.0.rc4/lib/rails/rack/content_length.rb:28:in block in call' /Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/rack-1.3.0/lib/rack/lock.rb:7:inblock in each'
/Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:135:in block (2 levels) in each' /Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:135:ineach'
/Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:135:in block in each' /Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:134:ineach_key'
/Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/activemodel-3.1.0.rc4/lib/active_model/errors.rb:134:in each' /Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/actionpack-3.1.0.rc4/lib/action_dispatch/http/response.rb:43:ineach'
/Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/rack-1.3.0/lib/rack/lock.rb:7:in each' /Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/railties-3.1.0.rc4/lib/rails/rack/content_length.rb:26:incall'
/Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/railties-3.1.0.rc4/lib/rails/rack/debugger.rb:21:in call' /Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/railties-3.1.0.rc4/lib/rails/rack/log_tailer.rb:14:incall'
/Users/dbk/.rvm/gems/ruby-1.9.2-p180-patched@rails31/gems/rack-1.3.0/lib/rack/handler/webrick.rb:59:in service' /Users/dbk/.rvm/rubies/ruby-1.9.2-p180-patched/lib/ruby/1.9.1/webrick/httpserver.rb:111:inservice'
/Users/dbk/.rvm/rubies/ruby-1.9.2-p180-patched/lib/ruby/1.9.1/webrick/httpserver.rb:70:in run' /Users/dbk/.rvm/rubies/ruby-1.9.2-p180-patched/lib/ruby/1.9.1/webrick/server.rb:183:inblock in start_thread'

#gemfile

source 'http://rubygems.org'
gem 'rails', "3.1.0.rc4"#:git => "git://github.com/rails/rails.git", :branch => "3-1-stable"
gem 'sass'
gem 'coffee-script'
gem 'uglifier', :git => "git://github.com/lautis/uglifier.git"
gem "jquery-rails", :git => "git://github.com/rails/jquery-rails.git"
gem "pjax_rails", :git => "git://github.com/rails/pjax_rails.git"
gem "haml"
gem "tilt", :git => "git://github.com/rtomayko/tilt.git"

Authentication/Authorization

gem "devise", :git => "https://github.com/plataformatec/devise.git"
gem 'omniauth', '~> 0.2.0'
gem 'cancan'

Databases

gem "bson_ext", ">= 1.3.1"
gem "mongoid", ">= 2.0.2"
gem 'mongoid_i18n',:require => 'mongoid/i18n'
gem 'mongoid_slug', :require => 'mongoid/slug'
gem 'mongoid_geo', "> 0.6.0", :require => 'mongoid/geo'
gem 'mongo-rails-instrumentation', '
>0.2'
gem 'mysql2', '~> 0.2.7'
gem 'mysql'
#gem "mysql", "2.8.1"

Uploads/Image Processing

gem "carrierwave"
gem "mini_magick"

Controllers and views

gem 'to_lang'
gem "will_paginate", "~> 3.0.pre2"
gem 'inherited_resources'
gem 'simple_form'
gem 'sass-rails'#, :git => 'git://github.com/rails/sass-rails.git'
gem 'compass', :git => 'git://github.com/chriseppstein/compass.git',:branch => "master", :require => false
gem 'compass-960-plugin'
gem "coffee-filter", :git => "git://github.com/paulnicholson/coffee-filter.git"

Owner

spastorino commented Jul 11, 2011

js format always returns 200, it is used for scripting.

@spastorino spastorino closed this Jul 11, 2011

Contributor

josevalim commented Jul 11, 2011

I have fixed this issue recently in Rails.

Owner

spastorino commented Jul 11, 2011

Ya, I wasn't seeing the bytesize error anyways doesn't return 422. @tanordheim tests are going to fail anyways because of that.

@josevalim can you remember the commit or approximately when you committed it? Would be interesting to see the fix since I poked around quite a bit in what I believe was the correct code without figuring it out. I checked the commits for the last few days, but didn't find anything :)

Contributor

josevalim commented Jul 12, 2011

@dblock dblock referenced this issue in ruby-grape/grape Jul 26, 2016

Closed

Add Rails 5 to Appraisals #1456

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment