Home > ruby on rails > http_status_exceptions plugin in ruby on rails

http_status_exceptions plugin in ruby on rails

September 25th, 2008

http_status_exceptions is a simple plugin to enable the use of exceptions to generate responses with different HTTP status codes.

This can be used to cleanup your controller in handling edge-cases.
For instance, you could raise a HTTPStatus::Forbidden exception if the user is not authorized to perform restricted action, or you could raise a HTTPStatus::PaymentRequired if the user should renew its membership to your website. By default, this plugin will send an empty response with the desired HTTP status code. It is possible to respond with a customized error page as well. In the case of HTTPStatus::PaymentRequired, a response with a credit card payment form can be used, so that the user easily can renew his membership.

Installation

This plugin can be installed as a Ruby gem or as a Rails plugin (depecated).
Installation as a Ruby gem
Installing the plugin as a Ruby gem in your project is the recommended installation method. Add the following line to your config/environment.rb file:

Rails::Initializer.run do |config|
...
config.gem 'wvanbergen-http_status_exceptions', :lib => 'http_status_exceptions',
:source => 'http://gems.github.com'
end

Afterwards, run rake gems:install to actually download and install the gem on your system. Now, see Basic Usage to see how to make use of this plugin once it is enabled in your project.
Installation as a Rails plugin

It is possible to install http_status_exceptions as a classic Rails plugin as well, but this is deprecated. Use the following command in your project root:


script/plugin install git://github.com/wvanbergen/http_status_exceptions.git

Alternatively, you could download the plugin and put it in the vendor/plugins directory of your Rails application

Basic Usage

Once the plugin is installed, it will register a list of exceptions that you can raise in your controller code. See AvailableExceptions for the actual list of exceptions and their corresponding status codes.
Raising HTTPStatus exceptions
You can simply raise an HTTPStatus-exception as soon as the normal execution of your code should stop.

class BlogController < ApplicationController
def destroy
raise HTTPStatus::Forbidden, "You cannot delete blogs!" unless user.admin?
@blog = Blog.find(params[:id])
@blog.destroy
...
end
end

Raising exceptions works just as well in a before_filter:

class ApplicationController < ActionController::Base
before_filter :set_current_user
def set_current_user
@user = User.find(session[:user_id)
raise HTTPStatus::PaymentRequired, "Your account is expired" if @user.is_expired?
end
end

You can provide some additional details to the exception as well by passing an additional argument. This information can be used later on in the exception handler using the details function.

begin
raise HTTPStatus::Forbidden.new("message", {:restricted_object => @blog })
rescue HTTPStatus::Base => e
logger.error e.details[:restricted_object].inspect
end

Displaying an error page

Once an HTTPStatus exception is raised, the default exception handler will be called. By default, it will return an empty response with the correct HTTP status code. It can return an error page easily by creating a template for that particular exception. For instance, to create an error page for the HTTPStatus::NotFound (404) exception, you should create a template file with the following name: app/views/shared/http_status/not_found.html.erb. The current layout will be applied to the template. The template file could look something like this:

Note that by using the .html .erb extension, this template will only be used for HTML formatted requests; if the same exception is raised with XML as format, the response will remain empty. In theory, you could create the file app/views/shared/http_status/not_found.xml.builder to generate an error page for XML requests. A template file without a format app/views/shared/http_status/not_found.erb will be used for any format. This is basically the same way Rails handles templates.

Customization

This plugin consists of two parts, the HTTPStatus exceptions and the default exception handler. Both of these can be changed easily to fit your own needs.
Changing the exception handler

This plugin uses rescue_from to catch all HTTPStatus exceptions and simply calls the http_status_exception method to handle it. You can reimplement this method in your application controller if you wish to customize the handling of these exceptions.
This is the default implementation of this method:

def http_status_exception(exception)
@exception = exception
render(:template => exception.template, :status => exception.status)
rescue ActionView::MissingTemplate
head(exception.status)
end

Altering HTTPStatus::Base

All exception classes are automatically generated and based on the HTTPStatus::Base. You can reopen this class to change its functionality, which in turn will then be available to all exception classes. This can be done by adding a file to your config/initializations directory:

# Change the path from which the error page templates are loaded.
# Default value: 'shared/http_status'
HTTPStatus::Base.template_path = 'layouts/http_status'
# Add a method to all exception classes
class HTTPStatus::Base
def hello_world
'Hello world!'
end
end

Labels:http_status_exceptions, HTTPStatus-exception, exception, httpstatus, ruby on rails plugin, http_status_exceptions ror plugin

Share This Post

Random Posts

ruby on rails , , , , ,

  1. October 21st, 2009 at 12:36 | #1

    Thanks for this nice write-up of http_status_exceptions. Glad to see there is interest in this Rails plugin. :-)

    Just a quick note: because Github does not build gems anymore, I moved the plugin to gemcutter. The gem declaration in environment.rb should become:

    config.gem ‘http_status_exceptions’, :source => ‘http://gemcutter.org’

    Cheers,
    Willem

  1. No trackbacks yet.