BetterErrors / better_errors

Better error page for Rack apps
MIT License
6.88k stars 436 forks source link

"Session expired" when using REPL #40

Closed pelargir closed 11 years ago

pelargir commented 11 years ago

I'm trying to use the REPL from an exception raised inside a presenter object, but when I try to reference any local vars I get this:

Session expired

undefined

Any ideas?

haileys commented 11 years ago

better_errors only keeps the most recent exception around for the sake of preventing memory leaks. If you have another exception occur after the one you're currently investigating, it'll tell you that your session has expired.

pelargir commented 11 years ago

I'm 99% sure that only one exception is being thrown in this situation. I can inspect the values of "primitive" vars just fine (integers, strings, etc) but when I try to inspect objects in the local scope, I get "Session expired."

haileys commented 11 years ago

I have a theory on what might be causing this, I'll try to fix it tonight

On Thursday, 13 December 2012 at 1:03 PM, Matthew Bass wrote:

I'm 99% sure that only one exception is being thrown in this situation. I can inspect the values of "primitive" vars just fine (integers, strings, etc) but when I try to inspect objects in the local scope, I get "Session expired."

— Reply to this email directly or view it on GitHub (https://github.com/charliesome/better_errors/issues/40#issuecomment-11319173).

octplane commented 11 years ago

:+1: for some fix. I have the same issue here on our application. Even inspecting local variables leads to variable-but-swift session expiration. No other exception is raised in the mean time.

Cool gem, still !

scootklein commented 11 years ago

+1

nfm commented 11 years ago

+1. I can print params once, but on subsequent attempts, I get Session expired.

>> p params
=> {"action"=>"dashboard", "controller"=>"accounts"}
>> p params
Session expired
>> undefined

From a pretty stock exception I caused:

def dashboard
  current_user.name = bar
end

undefined local variable or method `bar' for #<AccountsController:0x00000006fdd328>

I believe this is caused by unicorn. I'm guessing it's to do with having multiple workers but haven't dug into the code at all. I don't get the same error if I use Thin.

haileys commented 11 years ago

@nfm Multiple workers certainly will cause an issue. Better Errors works by keeping the error state around in memory. If you send a REPL or local variable request back, that will need to run on the same worker the error happened on.

nfm commented 11 years ago

Wow, thanks for the quick response. Awesome gem btw :)

Can others in this thread comment on whether they're using multiple workers for their server?

octplane commented 11 years ago

I'm definitely using multiple workers on my development box. Unicorns, even...

The only very dirty workaround I see would be to store the worker pid in the error state and the retry the command until the correct worker answers. How awful :(

Pierre Baillet (en vadrouille)

Le dimanche 16 décembre 2012 à 05:14, Nicholas Firth-McCoy a écrit :

Wow, thanks for the quick response. Awesome gem btw :) Can others in this thread comment on whether they're using multiple workers for their server?

— Reply to this email directly or view it on GitHub (https://github.com/charliesome/better_errors/issues/40#issuecomment-11414080).

haileys commented 11 years ago

I don't intend to support multiple development workers, simply because it adds a huge amount of extra complexity and it isn't a very common use case

pelargir commented 11 years ago

Yes, I am using multiple workers via Unicorn. So that would explain the behavior.

haileys commented 11 years ago

Cool, good to know that was the cause.

andersonfreitas commented 11 years ago

This is exactly what I was looking for.

I'm using Pow and by default it spawns 3 workers, so I had to add to my ~/.powconfig the following line export POW_WORKERS=1

maxim commented 11 years ago

It's not uncommon for a request to your app to need another request to your app to succeed. In my case I have a parallel process that depends on some assets to be served by unicorn while http request is waiting. Having only 1 worker turns this into a deadlock. Perhaps the complexity of supporting >1 worker could, after all, be worth it?

haileys commented 11 years ago

There is a significant amount of complexity in supporting multiple workers. Better Errors relies on leaving a bunch of data in memory in the process where the exception was thrown (eg. the binding stack).

It's not possible to migrate these objects between processes, so the only way to support multiple workers is to have workers connect to other workers. If you go down this path, then you also have to worry about how workers 'discover' which worker they should connect to when they need to use the binding objects.

I don't think supporting an uncommon use case like this is worth all the extra complexity.

maxim commented 11 years ago

For what it's worth maybe there is a simpler approach: teach unicorn/pow to use a worker pid supplied in a request header. Every app response would have worker pid injected via simple middleware. Every eval request would then supply it in the header. Unicorn extension would send it to the correct worker. I know it's still complex, but perhaps not as complex as IPC.

octplane commented 11 years ago

I think @maxim solution is indeed the most elegant as it also removes the IPC complexity from @charliesome excellent Betters Errors. However, adding that kind of feature to unicorn is going to be a bit of hardcore negotiation with the maintainer of the project, Eric Wong, which is a very good but hard to convince product manager...

maxim commented 11 years ago

I certainly didn't mean that we should change unicorn. Merely extend it with another gem, something like better_errors-unicorn.

On Fri, Mar 15, 2013 at 4:52, Pierre Baillet notifications@github.com="mailto:notifications@github.com"> wrote: I think @maxim solution is indeed the most elegant as it also removes the IPC complexity from @charliesome excellent Betters Errors. However, adding that kind of feature to unicorn is going to be a bit of hardcore negotiation with the maintainer of the project, Eric Wong, which is a very good but hard to convince product manager...

— Reply to this email directly or view it on GitHub.

On Fri, Mar 15, 2013 at 4:52 AM, Pierre Baillet notifications@github.com wrote:

I think @maxim solution is indeed the most elegant as it also removes the IPC complexity from @charliesome excellent Betters Errors. However, adding that kind of feature to unicorn is going to be a bit of hardcore negotiation with the maintainer of the project, Eric Wong, which is a very good but hard to convince product manager...

Reply to this email directly or view it on GitHub: https://github.com/charliesome/better_errors/issues/40#issuecomment-14949852

joevandyk commented 11 years ago

I'm running into the same problem as @maxim, fwiw. I have to have multiple workers for my app, and so better_errors's repl isn't working for me.

henrik commented 11 years ago

The README addition in 2c5d3bc48bfb82f5ba6114572f20f87f7425e9f3 is great, though I didn't check there first – maybe tweaking the error message could be even more helpful? Happy to contribute a pull request if @charliesome agrees. Perhaps "Session expired (Using a multi-worker server? See README.)"

henrik commented 11 years ago

Oh, and if you use Unicorn and temporarily want to decrease the number of workers:

ps aux | grep unicorn
# let's assume master has pid 12345
kill -SIGTTOU 12345  # remove one worker
jalcine commented 10 years ago

I've used @henrik's solution and tried running it with Webrick as well and I've come to no avail :/

TigerWolf commented 10 years ago

I am getting this problem with Thin. Is Thin also multi threaded by default?

finbarr commented 10 years ago

I managed to fix this in unicorn by forcing the number of worker processes to be 1. better_errors is so much better now!

luigi7up commented 9 years ago

Guys, I am using Unicorn and in my dev I have set it to only one worker, but still when I raise an exception in my view I get "session expired"?!

if ENV['RAILS_ENV']=="development"
  worker_processes Integer 1
  timeout 5000
else
  worker_processes Integer(ENV["WEB_CONCURRENCY"] || 2)  
  timeout 15
end
henrik commented 9 years ago

Have you verified that it only starts one worker (e.g. with "ps ax | grep unicorn")? I'm not sure whether RAILS_ENV is set at that point.

On Sat, Nov 1, 2014 at 2:38 PM, Luka notifications@github.com wrote:

Guys, I am using Unicorn and in my dev I have set it to only one worker, but still when I raise an exception in my view I get "session expired"?!

if ENV['RAILS_ENV']=="development" worker_processes Integer 1 timeout 5000 else worker_processes Integer(ENV["WEB_CONCURRENCY"] || 2) timeout 15 end

— Reply to this email directly or view it on GitHub https://github.com/charliesome/better_errors/issues/40#issuecomment-61368436 .

luigi7up commented 9 years ago

Hi Henrik,

Yes, it starts only one worker, but there are two processes worker and a master...

41037   0,0  3,1  2836428 260424 s002  S+ ... 1:23.63 unicorn worker[0] -p 5000 -c ./config/unicorn.rb
41030   0,0  1,5  2641736 128944 s002  S+ ... 0:06.96 unicorn master -p 5000 -c ./config/unicorn.rb

thanks