I'm surprised that if you removed the exception block, that you still get
your exception message (" Expecting to have order, but session doesn't have
one"). Maybe I am not understanding you.
Anyways, here is what I mean about narrowing your exception handling. This
might not be your problem, but it's a good alternative to rescuing every
exception:
class HomeGrownError < StandardError
end
...
...
...
protected
# This is where I am caching the exceptions.
def check_for_existing_order
unless current_order?
begin
raise HomeGrownError("Expecting to have order, but session doesn't
have one")
rescue HomeGrownError => exception
ExceptionNotifier::Notifier.exception_notification(request.env,
exception).deliver
ensure
redirect_to root_path unless Rails.env.development?
return
end
end
end
On Thu, Dec 29, 2011 at 10:13 AM, Ylan Segal <[email protected]> wrote:
> Ben,
>
> def current_order?
> session[:order_id]
> end
>
> Since the problem only happens on production, I wasn't really getting full
> stack trace information if I let the exception through. That is why I added
> the rescue block in the first place: It sends me all the info with
> ExceptionNotifier. Without the rescue block, eventually what happens is a
> call a property that is nil on the order and that throws an exception, but
> the problem is that the order_id is nill in the first place and it
> shouldn't be.
>
> Here is what that output looks like:
>
> A RuntimeError occurred in orders#show:
>
> Expecting to have order, but session doesn't have one
> app/controllers/lbd/orders_controller.rb:124:in `check_for_existing_order'
>
> -------------------------------
> Request:
> -------------------------------
>
> * URL : http://www.edited.com/order
> * IP address: 184.73.92.227
> * Parameters: {"action"=>"show", "controller"=>"lbd/orders"}
> * Rails root: /app
>
> -------------------------------
> Session:
> -------------------------------
>
> * session id: "8913455d4a9e22b76d48c438f90aaea6"
> * data: {"session_id"=>"8913455d4a9e22b76d48c438f90aaea6"}
>
>
> -------------------------------
> Environment:
> -------------------------------
>
> * GATEWAY_INTERFACE : CGI/1.2
> * HTTP_ACCEPT : */*
> * HTTP_ACCEPT_ENCODING : gzip
> * HTTP_CONNECTION : close
> * HTTP_HOST : www.edited.com
> * HTTP_USER_AGENT : Mozilla/5.0 (Windows
> NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1 SmartLinksAddon
> * HTTP_VERSION : HTTP/1.1
> * HTTP_VIA : 1.1
> web02.mashlogic.local:3028 (squid/2.7.STABLE9)
> * HTTP_X_FORWARDED_FOR : 127.0.0.1,
> 50.17.249.10, 10.114.118.95
> * HTTP_X_FORWARDED_PORT : 80
> * HTTP_X_FORWARDED_PROTO : http
> * HTTP_X_HEROKU_DYNOS_IN_USE : 1
> * HTTP_X_HEROKU_QUEUE_DEPTH : 0
> * HTTP_X_HEROKU_QUEUE_WAIT_TIME : 3
> * HTTP_X_REAL_IP : 10.114.118.95
> * HTTP_X_REQUEST_START : 1325180702283
> * HTTP_X_VARNISH : 2592570555
> * PATH_INFO : /order
> * QUERY_STRING :
> * REMOTE_ADDR : 10.66.162.3
> * REQUEST_METHOD : GET
> * REQUEST_PATH : /order
> * REQUEST_URI : /order
> * SCRIPT_NAME :
> * SERVER_NAME : www.edited.com
> * SERVER_PORT : 80
> * SERVER_PROTOCOL : HTTP/1.1
> * SERVER_SOFTWARE : thin 1.2.6 codename
> Crazy Delicious
> * action_controller.instance : orders#show
> * action_dispatch.cookies :
> #<ActionDispatch::Cookies::CookieJar:0x0000000b4e3c38>
> * action_dispatch.parameter_filter : [:password,
> :credit_card, :payment_profile, /RAW_POST_DATA/, /RAW_POST_DATA/]
> * action_dispatch.remote_ip : 50.17.249.10
> * action_dispatch.request.accepts : [*/*]
> * action_dispatch.request.content_type :
> * action_dispatch.request.formats : [*/*]
> * action_dispatch.request.parameters : {"action"=>"show",
> "controller"=>"lbd/orders"}
> * action_dispatch.request.path_parameters : {:action=>"show",
> :controller=>"lbd/orders"}
> * action_dispatch.request.query_parameters : {}
> * action_dispatch.request.request_parameters : {}
> * action_dispatch.request.unsigned_session_cookie:
> {"session_id"=>"018022ab5db5fe76684e2d1a5867d8a8"}
> * action_dispatch.routes :
> #<ActionDispatch::Routing::RouteSet:0x0000000496b690>
> * action_dispatch.secret_token :
> 0d72ef374495f4ed8ae2bd664e0fbf43e8c4f1a71cef4fb11d23dcc19dd55d0bbfe3fb9c55e59b8fe509c5d2c3ca77976f23c5f39392121e8d77d8b68de4359c
> * action_dispatch.show_exceptions : true
> * async.callback : #<Method:
> Thin::Connection#post_process>
> * async.close :
> #<EventMachine::DefaultDeferrable:0x0000000b502660>
> * rack-cache.allow_reload : false
> * rack-cache.allow_revalidate : false
> * rack-cache.cache_key : Rack::Cache::Key
> * rack-cache.default_ttl : 0
> * rack-cache.entitystore : rails:/
> * rack-cache.metastore : rails:/
> * rack-cache.private_headers : ["Authorization",
> "Cookie"]
> * rack-cache.storage :
> #<Rack::Cache::Storage:0x00000003c61918>
> * rack-cache.use_native_ttl : false
> * rack-cache.verbose : true
> * rack.errors : #<IO:0x00000000b39890>
> * rack.input :
> #<StringIO:0x0000000b503038>
> * rack.multiprocess : false
> * rack.multithread : false
> * rack.request.cookie_hash : {}
> * rack.request.query_hash : {}
> * rack.request.query_string :
> * rack.run_once : false
> * rack.session :
> {"session_id"=>"018022ab5db5fe76684e2d1a5867d8a8",
> "abingo_identity"=>9991086208}
> * rack.session.options :
> {:key=>"_locum_session", :path=>"/", :domain=>nil, :expire_after=>nil,
> :secure=>false, :httponly=>true, :defer=>false, :renew=>false,
> :coder=>#<Rack::Session::Cookie::Base64::Marshal:0x000000058583b0>,
> :id=>"018022ab5db5fe76684e2d1a5867d8a8"}
> * rack.url_scheme : http
> * rack.version : [1, 0]
> * warden : Warden::Proxy:94837780
> @config={:default_scope=>:user, :scope_defaults=>{},
> :default_strategies=>{:user=>[:database_authenticatable]},
> :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x00000005d371b0>}
>
> * Process: 1
> * Server : 4950a26f-9aa2-4265-af61-f08d70fc8a30
>
> --
> Ylan Segal
> [email protected]
>
>
> On Dec 29, 2011, at 10:00 AM, Ben Wanicur wrote:
>
> > Sorry, I missed your def current_order? method (formatting is really bad
> on my computer here).... I would remove the exception handling (you are
> capturing everything with your rescue block), and see what more information
> you can gather.
> >
> >
> >
> > On Thu, Dec 29, 2011 at 9:43 AM, Ylan Segal <[email protected]> wrote:
> > Sure. Here we go:
> >
> > #config/session_store.rb
> > Locum::Application.config.session_store :cookie_store, :key =>
> '_locum_session'
> >
> > #ApplicationController.rb
> > def current_order
> > if session[:order_id]
> > current_order = Order.find(session[:order_id])
> > end
> > if session[:order_id].nil?
> > current_order = Order.new
> > end
> > current_order
> > end
> >
> > def current_order?
> > session[:order_id]
> > end
> >
> > #OrdersController (inherits from Application Controller)
> > before_filter :check_for_existing_order, :except => :except =>
> [:add_item]
> >
> > # Users cannot see any other action on the app until they have gone
> through add_item.
> > def add_item
> > @order = current_order
> > @order.save
> > session[:order_id] = @order.id
> > variant = Variant.where(:sku => params[:variant_sku]).first
> > quantity = params[:quantity].to_i
> > @order.add_item(variant, quantity) unless variant.nil?
> > redirect_to order_path
> > end
> >
> > def show
> > @order = current_order
> > end
> >
> > def update
> > @order = current_order
> > @order.attributes = params[:order]
> > if @order.save
> > flash[:notice] = 'Your cart has been updated successfully'
> > else
> > flash[:alert] = "Your cart could not be updated:
> #{@order.errors.full_messages.join(',')}"
> > end
> > redirect_to order_path
> > end
> >
> > protected
> > # This is where I am caching the exceptions.
> > def check_for_existing_order
> > unless current_order?
> > begin
> > raise "Expecting to have order, but session doesn't have one"
> > rescue => exception
> > ExceptionNotifier::Notifier.exception_notification(request.env,
> exception).deliver
> > ensure
> > redirect_to root_path unless Rails.env.development?
> > return
> > end
> > end
> > end
> >
> > #config/routes.rb
> > resource :order, :except => [:destroy] do
> > member do
> > get :checkout
> > post :add_item
> > end
> > end
> >
> > I added the important parts (I think). Thanks for the help!
> >
> > --
> > Ylan Segal
> > [email protected]
> >
> > On Dec 29, 2011, at 9:24 AM, Ben Wanicur wrote:
> >
> > > Can you post your code Ylan ? Also, can you include and session store
> config files as well ?
> > >
> > > On Thu, Dec 29, 2011 at 9:21 AM, Ylan Segal <[email protected]>
> wrote:
> > > Fellow Rubyists,
> > >
> > > I have been scratching my head on this one for a while: I have an
> e-commerce app in production with pretty standard add-to-cart
> functionality. Whenever a user starts an order, I add the order id to the
> session and read it back on subsequent requests (like showing the cart,
> checkout form, etc). By and large, this works as expected in my tests and
> testing with local browsers.
> > >
> > > However, for a small number of my users, the session doesn't seems to
> keep the order id. In actions where I would expect the order id to be
> there, it is not. For example, I have a OrdersController#update action
> that, well, updates the order. Following convention, that actions forwards
> to OrdersController#show. Since the session[:order_id] was present in
> #update, I would obviously expect it to be set in #show, and for most users
> it is, but for some it is not. I am obviously, checking that the user is
> not visiting #show before #update or #create has been called.
> > >
> > > Random stuff that I think might make a difference
> > >
> > > * It is not restricted to any one browser/version. It happens with IE,
> Firefox, etc.
> > > * It happens with browsers that have cookies (I can see when analyzing
> requests, that the cookies headers are being sent, it just that the session
> doesn't contain the expected variable/value).
> > > * Running Rails 3.1 on heroku with default session store.
> > >
> > > Currently, my only hunch is that the users browser is not sending the
> latest version of a cookie (with the order_id set in the session) but the
> original one generated when the first visited the site (where the
> session[:order_id] has not been set).
> > >
> > > Has anyone experiences something like this? Would using another kind
> of cookie store solve this?
> > >
> > > Thanks for the help,
> > >
> > > --
> > > Ylan Segal
> > > [email protected]
> > > Tel: +1-858-224-7421
> > > Fax: +1-858-876-1799
> > >
> > > --
> > > SD Ruby mailing list
> > > [email protected]
> > > http://groups.google.com/group/sdruby
> > >
> > >
> > > --
> > > SD Ruby mailing list
> > > [email protected]
> > > http://groups.google.com/group/sdruby
> >
> > --
> > SD Ruby mailing list
> > [email protected]
> > http://groups.google.com/group/sdruby
> >
> >
> > --
> > SD Ruby mailing list
> > [email protected]
> > http://groups.google.com/group/sdruby
>
> --
> SD Ruby mailing list
> [email protected]
> http://groups.google.com/group/sdruby
>
--
SD Ruby mailing list
[email protected]
http://groups.google.com/group/sdruby