Help with exceptions in UI

Hi Ruby forum,
I’m pretty new to Rails and Ruby and I’m trying to figure out how to
avoid having ugly stack dumps in my applications. I’m trying build a
Login module following the “Rails Recipes”. It works fine when users
enter correct data, but of course, when the fields are blank there’s an
exception in the UI.

My question is: how do I handle/catch the exception so that users won’t
see the rails messages? I just want to drop them off on the page they
were on with a “you’re being naughty” message.

Here is my model code:

  def self.authenticate(username, password)
    user = User.find(:first, :conditions => ['username = ?', username])
    if user.blank? ||
      Digest::SHA256.hexdigest(password + user.password_salt) !=
user.password_hash
      raise "Username or password invalid"
    end
    user
  end

And controller:

def signin
    if request.post?
      session[:user] = User.authenticate(params[:username],
params[:password]).id
      redirect_to :action => session[:intended_action],
                      :controller => session[:intended_controller]
    end
  end

Two possible ideas:

a) Put begin/rescue around the call to authenticate in the controller;
if exception is thrown, reload page with error message.

b) Change authenticate to return nil intead of throwing; then just check
if you got a user back in your controller.

By the way, rails only shows stack traces in development mode. In
production the user would just get a 500 page… still not what you
want, but you don’t have to worry about stack traces being shown to the
world.

b

onemind wrote:

user = User.find(:first, :conditions => [‘username = ?’, username])

Always challenge code that raises exceptions - there are usually ways
around
it. Specifically, in a pinch, that could be this:

user = User.find(:first, :conditions => [‘username = ?’, username])
rescue nil

(All on one line.)

That has the added benefit of hiding any kind of error, not just “user
not
found” errors. Because you probably don’t need that benefit, you can
make
things shorter and better at the same time:

user = User.find_by_username(username)

Any find_by_* method returns ‘nil’ if the target ain’t found.


Phlip
Test Driven Ajax (on Rails) [Book]
“Test Driven Ajax (on Rails)”
assert_xpath, assert_javascript, & assert_ajax