TAGS:

ruby  rails  exception  handler 

Series:

1- Using Rails Exception Handler Gem.

First, Add rails_exception_handler to Gemfile.

gem 'rails_exception_handler', "~> 2"

Then, Make bundle install.

2- Generate an initializer.

rails g rails_exception_handler:install

Open config/initializers/rails_exception_handler.rb, and choose the environments you want to handle exceptions with.

config.environments = [:production, :test, :development]

Also, You can use another layout in the case of missing application layout using home layout in views/layouts or any other layout as error in our tutorial.

config.fallback_layout = 'error'

You can change the error message generated with exception as:

config.responses = {
  :default => "<h1>500</h1><p>Internal server error</p>",
  :not_found => "<h1>Ops, The page you write is not found</h1><p>Page not found</p>"
}

Also, You can map the relation between the error type and the message related as:

config.responses = {
    'ActiveRecord::RecordNotFound' => :not_found,
    'ActionController::RoutingError' => :not_found,
    'AbstractController::ActionNotFound' => :not_found
  }

3- Storing the exception

config.storage_strategies = [:active_record]
 config.active_record_store_in = {
  :database => 'development', # Production in the production environment
  :record_table => 'error_messages' # The table name will be created.
 }

Note, We will create error_messages table in the same database.

Then, Create a migration file for error_message as :

rails g migration error_message

Then, Edit the generated file to be :

class ErrorMessages < ActiveRecord::Migration
  def change
     create_table :error_messages do |t|
      t.text :class_name
      t.text :message
      t.text :trace
      t.text :params
      t.text :target_url
      t.text :referer_url
      t.text :user_agent
      t.string :user_info
      t.string :app_name
      t.string :doc_root

      t.timestamps
    end
  end
end

Then, Make migration:

rake db:migrate

4- Delete Error Pages From Public Folder.

This is important step.

You must delete or rename 404,422,500 error pages form public folder.

5- Create a Model To Deal With `error_message` Table .

In app/model folder create error_message.rb file and type:

class ErrorMessage < ActiveRecord::Base
end

6-Storing Exceptions In Database.

First, You must decide if you will store exceptions into the save application database or in another database.

If you decided to store exceptoins in another database, then you have to create state that in /config/database.yml.

But, We will use our database in this tutorial, and database.yml as it is and the /config/initializers/rails_exception_handler.rb will be:

RailsExceptionHandler.configure do |config|
  config.environments = [:development, :test, :production]                # Defaults to [:production]
  config.fallback_layout = 'error'                                         # Defaults to 'application'
  # config.after_initialize do
  #   # This block will be called after the initialization is done.
  #   # Usefull for interaction with authentication mechanisms, which should
  #   # only happen when the exception handler is enabled.
  # end
  # config.filters = [                                                      # No filters are  enabled by default
  #   :all_404s,
  #   :no_referer_404s,
  #   :anon_404s,
  #   {:user_agent_regxp => /\b(ApptusBot|TurnitinBot|DotBot|SiteBot)\b/i},
  #   {:target_url_regxp => /\.php/i},
  #   {:referer_url_regxp => /problematicreferer/i}
  # ]
  #
  # !!! IMPORTANT !!!
  # You must remove public/500.html and public/404.html for these to have any effect
  config.responses = {
    :default => "<h1>500</h1><p>Internal server error</p>",
    :not_found => "<h1>Ops, The page you write is not found</h1><p>Page not found</p>"
  }

  # All errors are mapped to the :default response unless overridden here
  config.response_mapping = {
    'ActiveRecord::RecordNotFound' => :not_found,
    'ActionController::RoutingError' => :not_found,
    'AbstractController::ActionNotFound' => :not_found
  }

  config.storage_strategies = [:active_record] # Available options: [:active_record, :rails_log, :remote_url => {:target => 'http://example.com'}]

  # Change database/table for the active_record storage strategy
  config.active_record_store_in = {
   :database => 'development', # your database is development in this example but must be `production` in production environment
   #and you must state the name if you will use another database.
   :record_table => 'error_messages' #the name of the table
  }


  config.store_request_info do |storage,request|
    storage[:target_url] =    request.url
    storage[:referer_url] =   request.referer
    storage[:params] =        request.params.inspect
    storage[:user_agent] =    request.user_agent
  end

  config.store_exception_info do |storage,exception|
    storage[:class_name] =   exception.class.to_s
    storage[:message] =      exception.to_s
    storage[:trace] =        exception.backtrace.join("\n")
  end

  config.store_environment_info do |storage,env|
    storage[:doc_root] =      env['DOCUMENT_ROOT']
  end

  config.store_global_info do |storage|
    storage[:app_name] =     Rails.application.class.parent_name
    storage[:created_at] =   Time.now
  end
  #config.store_user_info = {:method => :current_user, :field => :email} # Helper method for easier access to current_user
end

All these steps in this tutorial video :


Source on github.com

Great Note, Every time you change any file in config/initializers, You must restart server.