This post is a follow on from the Creating a login form with Ruby on Rails post. At the end of that post we had a login form to enter your Basecamp username and password, but it didn't cope very well if you typed in the wrong username or password. In this post we're going to handle this by displaying a message on the form saying the username or password is incorrect, and giving the user another go at logging on.
Unfortunately this will be my last post on Basecamp/Rails integration, as I'm no longer working on this project.
If we look at the error message we get when the login details are incorrect, we see a couple of things:
File does not exist: HTTP Basic: Access denied. app/controllers/logins_controller.rb:5:in `create'
There is actually a lot more there, but this is the important stuff, the error message and where the error occurred. The error is occurring in the
Basecamp.get_token line, so we need to handle this using the Ruby exception handling, i.e. a
Putting this into
app/controllers/logins_controller.rb we end up with:
begin session[:token] = Basecamp.get_token rescue Exception => e flash[:error] = e.message redirect_to new_login_path else redirect_to session[:original_url] end
Basecamp.get_token method gets an error, then everything between the
rescue and the
else will be executed. If all is OK, everything between the
else and the
end is executed.
In the error handling code we do two things, first set
flash[:error] to the error message, and then redirect back to the login form, i.e.
new_login_url. So what's this
The flash hash is actually similar to the session hash I described in the post on creating the login form, i.e. it is used to hold information between browser requests. There is however one difference between flash and session, the contents of flash are only held until the next request, after which it is automatically deleted.
A common use of the flash is for passing errors messages from one request to the next, which is what we are doing here. In the controller we set
flash[:error] to the error message. Then in the view for the login form (i.e.
app/views/login/new.html.erb) we can add a line to display the error, as shown below:
<%= form_tag :action => :create do %> <%= label_tag :user, 'Username: ' %><br> <%= text_field_tag :user %><br> <%= label_tag :password, 'Password: ' %><br> <%= password_field_tag :password %><br> <%= submit_tag 'Login' %> <% end %> <%= flash[:error] %>
A More Helpful Error Message
Finally, let's make the error message a bit more friendly.
begin session[:token] = Basecamp.get_token rescue Exception => e flash[:error] = e.message flash[:error] = 'Incorrect username or password' if flash[:error].match(/Access denied/) redirect_to new_login_url else redirect_to session[:original_url] end