rollbar 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +20 -0
- data/.travis.yml +17 -0
- data/CHANGELOG.md +90 -0
- data/Gemfile +8 -0
- data/LICENSE +22 -0
- data/README.md +165 -0
- data/Rakefile +14 -0
- data/THANKS +10 -0
- data/lib/generators/rollbar/rollbar_generator.rb +53 -0
- data/lib/generators/rollbar/templates/initializer.rb +28 -0
- data/lib/rollbar.rb +358 -0
- data/lib/rollbar/configuration.rb +64 -0
- data/lib/rollbar/delayed_job.rb +25 -0
- data/lib/rollbar/exception_reporter.rb +24 -0
- data/lib/rollbar/goalie.rb +33 -0
- data/lib/rollbar/middleware/rack/builder.rb +21 -0
- data/lib/rollbar/middleware/rack/test_session.rb +31 -0
- data/lib/rollbar/middleware/rails/show_exceptions.rb +26 -0
- data/lib/rollbar/rack.rb +9 -0
- data/lib/rollbar/rails.rb +22 -0
- data/lib/rollbar/rails/controller_methods.rb +28 -0
- data/lib/rollbar/railtie.rb +37 -0
- data/lib/rollbar/rake.rb +9 -0
- data/lib/rollbar/rake_tasks.rb +60 -0
- data/lib/rollbar/request_data_extractor.rb +115 -0
- data/lib/rollbar/sidekiq.rb +25 -0
- data/lib/rollbar/version.rb +3 -0
- data/rollbar.gemspec +24 -0
- data/spec/controllers/home_controller_spec.rb +180 -0
- data/spec/dummyapp/.gitignore +73 -0
- data/spec/dummyapp/Rakefile +7 -0
- data/spec/dummyapp/app/assets/javascripts/application.js +3 -0
- data/spec/dummyapp/app/assets/stylesheets/application.css.scss +37 -0
- data/spec/dummyapp/app/controllers/application_controller.rb +3 -0
- data/spec/dummyapp/app/controllers/home_controller.rb +25 -0
- data/spec/dummyapp/app/controllers/users_controller.rb +17 -0
- data/spec/dummyapp/app/helpers/.gitkeep +0 -0
- data/spec/dummyapp/app/mailers/.gitkeep +0 -0
- data/spec/dummyapp/app/models/.gitkeep +0 -0
- data/spec/dummyapp/app/models/user.rb +10 -0
- data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +27 -0
- data/spec/dummyapp/app/views/devise/registrations/new.html.erb +20 -0
- data/spec/dummyapp/app/views/devise/shared/_links.html.erb +25 -0
- data/spec/dummyapp/app/views/home/cause_exception.html.erb +1 -0
- data/spec/dummyapp/app/views/home/index.html.erb +4 -0
- data/spec/dummyapp/app/views/home/report_exception.html.erb +1 -0
- data/spec/dummyapp/app/views/layouts/_messages.html.erb +5 -0
- data/spec/dummyapp/app/views/layouts/_navigation.html.erb +21 -0
- data/spec/dummyapp/app/views/layouts/application.html.erb +25 -0
- data/spec/dummyapp/app/views/users/index.html.erb +8 -0
- data/spec/dummyapp/app/views/users/show.html.erb +3 -0
- data/spec/dummyapp/config.ru +4 -0
- data/spec/dummyapp/config/application.rb +60 -0
- data/spec/dummyapp/config/boot.rb +10 -0
- data/spec/dummyapp/config/database.yml +25 -0
- data/spec/dummyapp/config/environment.rb +5 -0
- data/spec/dummyapp/config/environments/development.rb +37 -0
- data/spec/dummyapp/config/environments/production.rb +67 -0
- data/spec/dummyapp/config/environments/test.rb +37 -0
- data/spec/dummyapp/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummyapp/config/initializers/devise.rb +233 -0
- data/spec/dummyapp/config/initializers/inflections.rb +15 -0
- data/spec/dummyapp/config/initializers/mime_types.rb +5 -0
- data/spec/dummyapp/config/initializers/rollbar.rb +20 -0
- data/spec/dummyapp/config/initializers/secret_token.rb +7 -0
- data/spec/dummyapp/config/initializers/session_store.rb +8 -0
- data/spec/dummyapp/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummyapp/config/locales/devise.en.yml +58 -0
- data/spec/dummyapp/config/locales/en.yml +5 -0
- data/spec/dummyapp/config/routes.rb +14 -0
- data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +46 -0
- data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +5 -0
- data/spec/dummyapp/db/schema.rb +35 -0
- data/spec/dummyapp/db/seeds.rb +12 -0
- data/spec/dummyapp/lib/assets/.gitkeep +0 -0
- data/spec/dummyapp/public/404.html +26 -0
- data/spec/dummyapp/public/422.html +26 -0
- data/spec/dummyapp/public/500.html +25 -0
- data/spec/dummyapp/public/favicon.ico +0 -0
- data/spec/dummyapp/script/rails +6 -0
- data/spec/requests/home_spec.rb +48 -0
- data/spec/rollbar_spec.rb +426 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/support/devise.rb +3 -0
- metadata +282 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Add new inflection rules using the following format
|
4
|
+
# (all these examples are active by default):
|
5
|
+
# ActiveSupport::Inflector.inflections do |inflect|
|
6
|
+
# inflect.plural /^(ox)$/i, '\1en'
|
7
|
+
# inflect.singular /^(ox)en/i, '\1'
|
8
|
+
# inflect.irregular 'person', 'people'
|
9
|
+
# inflect.uncountable %w( fish sheep )
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# These inflection rules are supported but not enabled by default:
|
13
|
+
# ActiveSupport::Inflector.inflections do |inflect|
|
14
|
+
# inflect.acronym 'RESTful'
|
15
|
+
# end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rollbar/rails'
|
2
|
+
Rollbar.configure do |config|
|
3
|
+
config.access_token = 'aaaabbbbccccddddeeeeffff00001111'
|
4
|
+
|
5
|
+
# By default, Rollbar will try to call the `current_user` controller method
|
6
|
+
# to fetch the logged-in user object, and then call that object's `id`,
|
7
|
+
# `username`, and `email` methods to fetch those properties. To customize:
|
8
|
+
# config.person_method = "my_current_user"
|
9
|
+
# config.person_id_method = "my_id"
|
10
|
+
# config.person_username_method = "my_username"
|
11
|
+
# config.person_email_method = "my_email"
|
12
|
+
|
13
|
+
# Add exception class names to the exception_level_filters hash to
|
14
|
+
# change the level that exception is reported at. Note that if an exception
|
15
|
+
# has already been reported and logged the level will need to be changed
|
16
|
+
# via the rollbar interface.
|
17
|
+
# Valid levels: 'critical', 'error', 'warning', 'info', 'debug', 'ignore'
|
18
|
+
# 'ignore' will cause the exception to not be reported at all.
|
19
|
+
# config.exception_level_filters.merge!('MyCriticalException' => 'critical')
|
20
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Your secret key for verifying the integrity of signed cookies.
|
4
|
+
# If you change this key, all old signed cookies will become invalid!
|
5
|
+
# Make sure the secret is at least 30 characters and all random,
|
6
|
+
# no regular words or you'll be exposed to dictionary attacks.
|
7
|
+
Dummy::Application.config.secret_token = '61f244779bab3ceba188492a31fb02b0a975fb64b93e217c03966ef065f5f1aba3b145c165defe0f8256e45cc6c526a60c9780a506a16e730815a3f812b5f9e9'
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
Dummy::Application.config.session_store :cookie_store, :key => '_dummy_session'
|
4
|
+
|
5
|
+
# Use the database for sessions instead of the cookie-based default,
|
6
|
+
# which shouldn't be used to store highly confidential information
|
7
|
+
# (create the session table with "rails generate session_migration")
|
8
|
+
# Dummy::Application.config.session_store :active_record_store
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
#
|
3
|
+
# This file contains settings for ActionController::ParamsWrapper which
|
4
|
+
# is enabled by default.
|
5
|
+
|
6
|
+
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
7
|
+
ActiveSupport.on_load(:action_controller) do
|
8
|
+
wrap_parameters :format => [:json]
|
9
|
+
end
|
10
|
+
|
11
|
+
# Disable root element in JSON by default.
|
12
|
+
ActiveSupport.on_load(:active_record) do
|
13
|
+
self.include_root_in_json = false
|
14
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Additional translations at https://github.com/plataformatec/devise/wiki/I18n
|
2
|
+
|
3
|
+
en:
|
4
|
+
errors:
|
5
|
+
messages:
|
6
|
+
expired: "has expired, please request a new one"
|
7
|
+
not_found: "not found"
|
8
|
+
already_confirmed: "was already confirmed, please try signing in"
|
9
|
+
not_locked: "was not locked"
|
10
|
+
not_saved:
|
11
|
+
one: "1 error prohibited this %{resource} from being saved:"
|
12
|
+
other: "%{count} errors prohibited this %{resource} from being saved:"
|
13
|
+
|
14
|
+
devise:
|
15
|
+
failure:
|
16
|
+
already_authenticated: 'You are already signed in.'
|
17
|
+
unauthenticated: 'You need to sign in or sign up before continuing.'
|
18
|
+
unconfirmed: 'You have to confirm your account before continuing.'
|
19
|
+
locked: 'Your account is locked.'
|
20
|
+
invalid: 'Invalid email or password.'
|
21
|
+
invalid_token: 'Invalid authentication token.'
|
22
|
+
timeout: 'Your session expired, please sign in again to continue.'
|
23
|
+
inactive: 'Your account was not activated yet.'
|
24
|
+
sessions:
|
25
|
+
signed_in: 'Signed in successfully.'
|
26
|
+
signed_out: 'Signed out successfully.'
|
27
|
+
passwords:
|
28
|
+
send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.'
|
29
|
+
updated: 'Your password was changed successfully. You are now signed in.'
|
30
|
+
updated_not_active: 'Your password was changed successfully.'
|
31
|
+
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
|
32
|
+
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
|
33
|
+
confirmations:
|
34
|
+
send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.'
|
35
|
+
send_paranoid_instructions: 'If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes.'
|
36
|
+
confirmed: 'Your account was successfully confirmed. You are now signed in.'
|
37
|
+
registrations:
|
38
|
+
signed_up: 'Welcome! You have signed up successfully.'
|
39
|
+
signed_up_but_unconfirmed: 'A message with a confirmation link has been sent to your email address. Please open the link to activate your account.'
|
40
|
+
signed_up_but_inactive: 'You have signed up successfully. However, we could not sign you in because your account is not yet activated.'
|
41
|
+
signed_up_but_locked: 'You have signed up successfully. However, we could not sign you in because your account is locked.'
|
42
|
+
updated: 'You updated your account successfully.'
|
43
|
+
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address."
|
44
|
+
destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.'
|
45
|
+
unlocks:
|
46
|
+
send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.'
|
47
|
+
unlocked: 'Your account has been unlocked successfully. Please sign in to continue.'
|
48
|
+
send_paranoid_instructions: 'If your account exists, you will receive an email with instructions about how to unlock it in a few minutes.'
|
49
|
+
omniauth_callbacks:
|
50
|
+
success: 'Successfully authenticated from %{kind} account.'
|
51
|
+
failure: 'Could not authenticate you from %{kind} because "%{reason}".'
|
52
|
+
mailer:
|
53
|
+
confirmation_instructions:
|
54
|
+
subject: 'Confirmation instructions'
|
55
|
+
reset_password_instructions:
|
56
|
+
subject: 'Reset password instructions'
|
57
|
+
unlock_instructions:
|
58
|
+
subject: 'Unlock Instructions'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Dummy::Application.routes.draw do
|
2
|
+
authenticated :user do
|
3
|
+
root :to => 'home#index'
|
4
|
+
end
|
5
|
+
root :to => "home#index"
|
6
|
+
devise_for :users
|
7
|
+
resources :users do
|
8
|
+
member { post :start_session }
|
9
|
+
end
|
10
|
+
|
11
|
+
match "/cause_exception" => "home#cause_exception"
|
12
|
+
match "/report_exception" => "home#report_exception"
|
13
|
+
match "/current_user" => "home#current_user"
|
14
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class DeviseCreateUsers < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table(:users) do |t|
|
4
|
+
## Database authenticatable
|
5
|
+
t.string :email, :null => false, :default => ""
|
6
|
+
t.string :encrypted_password, :null => false, :default => ""
|
7
|
+
|
8
|
+
## Recoverable
|
9
|
+
t.string :reset_password_token
|
10
|
+
t.datetime :reset_password_sent_at
|
11
|
+
|
12
|
+
## Rememberable
|
13
|
+
t.datetime :remember_created_at
|
14
|
+
|
15
|
+
## Trackable
|
16
|
+
t.integer :sign_in_count, :default => 0
|
17
|
+
t.datetime :current_sign_in_at
|
18
|
+
t.datetime :last_sign_in_at
|
19
|
+
t.string :current_sign_in_ip
|
20
|
+
t.string :last_sign_in_ip
|
21
|
+
|
22
|
+
## Confirmable
|
23
|
+
# t.string :confirmation_token
|
24
|
+
# t.datetime :confirmed_at
|
25
|
+
# t.datetime :confirmation_sent_at
|
26
|
+
# t.string :unconfirmed_email # Only if using reconfirmable
|
27
|
+
|
28
|
+
## Lockable
|
29
|
+
# t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
|
30
|
+
# t.string :unlock_token # Only if unlock strategy is :email or :both
|
31
|
+
# t.datetime :locked_at
|
32
|
+
|
33
|
+
## Token authenticatable
|
34
|
+
# t.string :authentication_token
|
35
|
+
|
36
|
+
|
37
|
+
t.timestamps
|
38
|
+
end
|
39
|
+
|
40
|
+
add_index :users, :email, :unique => true
|
41
|
+
add_index :users, :reset_password_token, :unique => true
|
42
|
+
# add_index :users, :confirmation_token, :unique => true
|
43
|
+
# add_index :users, :unlock_token, :unique => true
|
44
|
+
# add_index :users, :authentication_token, :unique => true
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# This file is auto-generated from the current state of the database. Instead
|
3
|
+
# of editing this file, please use the migrations feature of Active Record to
|
4
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
5
|
+
#
|
6
|
+
# Note that this schema.rb definition is the authoritative source for your
|
7
|
+
# database schema. If you need to create the application database on another
|
8
|
+
# system, you should be using db:schema:load, not running all the migrations
|
9
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
|
+
#
|
12
|
+
# It's strongly recommended to check this file into your version control system.
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(:version => 20121121184654) do
|
15
|
+
|
16
|
+
create_table "users", :force => true do |t|
|
17
|
+
t.string "email", :default => "", :null => false
|
18
|
+
t.string "encrypted_password", :default => "", :null => false
|
19
|
+
t.string "reset_password_token"
|
20
|
+
t.datetime "reset_password_sent_at"
|
21
|
+
t.datetime "remember_created_at"
|
22
|
+
t.integer "sign_in_count", :default => 0
|
23
|
+
t.datetime "current_sign_in_at"
|
24
|
+
t.datetime "last_sign_in_at"
|
25
|
+
t.string "current_sign_in_ip"
|
26
|
+
t.string "last_sign_in_ip"
|
27
|
+
t.datetime "created_at", :null => false
|
28
|
+
t.datetime "updated_at", :null => false
|
29
|
+
t.string "name"
|
30
|
+
end
|
31
|
+
|
32
|
+
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
|
33
|
+
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# This file should contain all the record creation needed to seed the database with its default values.
|
2
|
+
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
|
3
|
+
#
|
4
|
+
# Examples:
|
5
|
+
#
|
6
|
+
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
|
7
|
+
# Mayor.create(name: 'Emanuel', city: cities.first)
|
8
|
+
puts 'SETTING UP DEFAULT USER LOGIN'
|
9
|
+
user = User.create! :name => 'First User', :email => 'user@example.com', :password => 'please', :password_confirmation => 'please'
|
10
|
+
puts 'New user created: ' << user.name
|
11
|
+
user2 = User.create! :name => 'Second User', :email => 'user2@example.com', :password => 'please', :password_confirmation => 'please'
|
12
|
+
puts 'New user created: ' << user2.name
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/404.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
23
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/422.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The change you wanted was rejected.</h1>
|
23
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/500.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
23
|
+
</div>
|
24
|
+
</body>
|
25
|
+
</html>
|
File without changes
|
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HomeController do
|
4
|
+
let(:logger_mock) { double("Rails.logger").as_null_object }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
reset_configuration
|
8
|
+
Rollbar.configure do |config|
|
9
|
+
config.access_token = 'aaaabbbbccccddddeeeeffff00001111'
|
10
|
+
config.environment = ::Rails.env
|
11
|
+
config.root = ::Rails.root
|
12
|
+
config.framework = "Rails: #{::Rails::VERSION::STRING}"
|
13
|
+
config.logger = logger_mock
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "with broken request" do
|
18
|
+
it "should report uncaught exceptions" do
|
19
|
+
expect{ get 'current_user', nil, :cookie => '8%B' }.to raise_exception
|
20
|
+
|
21
|
+
exception_info = Rollbar.last_report[:body][:trace][:exception]
|
22
|
+
exception_info[:class].should == 'ArgumentError'
|
23
|
+
exception_info[:message].should == 'invalid %-encoding (8%B)'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "with error hiding deep inside" do
|
28
|
+
let!(:cookie_method_name){ :[] }
|
29
|
+
let!(:original_cookie_method){ ActionDispatch::Cookies::CookieJar.instance_method(cookie_method_name) }
|
30
|
+
let!(:broken_cookie_method){ Proc.new{ |name| "1" - 1 } }
|
31
|
+
|
32
|
+
before(:each) do
|
33
|
+
ActionDispatch::Cookies::CookieJar.send(:define_method, cookie_method_name, broken_cookie_method)
|
34
|
+
end
|
35
|
+
|
36
|
+
after(:each) do
|
37
|
+
ActionDispatch::Cookies::CookieJar.send(:define_method, cookie_method_name, original_cookie_method)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should report uncaught exceptions" do
|
41
|
+
expect{ get 'current_user' }.to raise_exception
|
42
|
+
|
43
|
+
exception_info = Rollbar.last_report[:body][:trace][:exception]
|
44
|
+
exception_info[:class].should == 'NoMethodError'
|
45
|
+
# exception_info[:message].should == 'undefined method `-\' for "1":String'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,426 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'socket'
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Rollbar do
|
6
|
+
|
7
|
+
context 'report_exception' do
|
8
|
+
before(:each) do
|
9
|
+
configure
|
10
|
+
Rollbar.configure do |config|
|
11
|
+
config.logger = logger_mock
|
12
|
+
end
|
13
|
+
|
14
|
+
begin
|
15
|
+
foo = bar
|
16
|
+
rescue => e
|
17
|
+
@exception = e
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:logger_mock) { double("Rails.logger").as_null_object }
|
22
|
+
|
23
|
+
it 'should report exceptions without person or request data' do
|
24
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
25
|
+
Rollbar.report_exception(@exception)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should not report anything when disabled' do
|
29
|
+
logger_mock.should_not_receive(:info).with('[Rollbar] Success')
|
30
|
+
Rollbar.configure do |config|
|
31
|
+
config.enabled = false
|
32
|
+
end
|
33
|
+
|
34
|
+
Rollbar.report_exception(@exception)
|
35
|
+
|
36
|
+
Rollbar.configure do |config|
|
37
|
+
config.enabled = true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should report exceptions with request and person data' do
|
42
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
43
|
+
request_data = {
|
44
|
+
:params => { :foo => "bar" },
|
45
|
+
:url => 'http://localhost/',
|
46
|
+
:user_ip => '127.0.0.1',
|
47
|
+
:headers => {},
|
48
|
+
:GET => { "baz" => "boz" },
|
49
|
+
:session => { :user_id => 123 },
|
50
|
+
:method => "GET",
|
51
|
+
}
|
52
|
+
person_data = {
|
53
|
+
:id => 1,
|
54
|
+
:username => "test",
|
55
|
+
:email => "test@example.com"
|
56
|
+
}
|
57
|
+
Rollbar.report_exception(@exception, request_data, person_data)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should ignore ignored exception classes' do
|
61
|
+
saved_filters = Rollbar.configuration.exception_level_filters
|
62
|
+
Rollbar.configure do |config|
|
63
|
+
config.exception_level_filters = { 'NameError' => 'ignore' }
|
64
|
+
end
|
65
|
+
|
66
|
+
logger_mock.should_not_receive(:info)
|
67
|
+
logger_mock.should_not_receive(:warn)
|
68
|
+
logger_mock.should_not_receive(:error)
|
69
|
+
|
70
|
+
Rollbar.report_exception(@exception)
|
71
|
+
|
72
|
+
Rollbar.configure do |config|
|
73
|
+
config.exception_level_filters = saved_filters
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should not report exceptions when silenced' do
|
78
|
+
Rollbar.should_not_receive :schedule_payload
|
79
|
+
|
80
|
+
begin
|
81
|
+
test_var = 1
|
82
|
+
Rollbar.silenced do
|
83
|
+
test_var = 2
|
84
|
+
raise
|
85
|
+
end
|
86
|
+
rescue => e
|
87
|
+
Rollbar.report_exception(e)
|
88
|
+
end
|
89
|
+
|
90
|
+
test_var.should == 2
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should report exception objects with no backtrace' do
|
94
|
+
payload = nil
|
95
|
+
Rollbar.stub(:schedule_payload) do |*args|
|
96
|
+
payload = MultiJson.load(args[0])
|
97
|
+
end
|
98
|
+
Rollbar.report_exception(StandardError.new("oops"))
|
99
|
+
payload["data"]["body"]["trace"]["frames"].should == []
|
100
|
+
payload["data"]["body"]["trace"]["exception"]["class"].should == "StandardError"
|
101
|
+
payload["data"]["body"]["trace"]["exception"]["message"].should == "oops"
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should return the exception data with a uuid, on platforms with SecureRandom' do
|
105
|
+
if defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
|
106
|
+
Rollbar.stub(:schedule_payload) do |*args| end
|
107
|
+
exception_data = Rollbar.report_exception(StandardError.new("oops"))
|
108
|
+
exception_data[:uuid].should_not be_nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'report_message' do
|
114
|
+
before(:each) do
|
115
|
+
configure
|
116
|
+
Rollbar.configure do |config|
|
117
|
+
config.logger = logger_mock
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
let(:logger_mock) { double("Rails.logger").as_null_object }
|
122
|
+
|
123
|
+
it 'should report simple messages' do
|
124
|
+
logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
|
125
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
126
|
+
Rollbar.report_message("Test message")
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should not report anything when disabled' do
|
130
|
+
logger_mock.should_not_receive(:info).with('[Rollbar] Success')
|
131
|
+
Rollbar.configure do |config|
|
132
|
+
config.enabled = false
|
133
|
+
end
|
134
|
+
|
135
|
+
Rollbar.report_message("Test message that should be ignored")
|
136
|
+
|
137
|
+
Rollbar.configure do |config|
|
138
|
+
config.enabled = true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should report messages with extra data' do
|
143
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
144
|
+
Rollbar.report_message("Test message with extra data", 'debug', :foo => "bar",
|
145
|
+
:hash => { :a => 123, :b => "xyz" })
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should not crash with circular extra_data' do
|
149
|
+
a = { :foo => "bar" }
|
150
|
+
b = { :a => a }
|
151
|
+
c = { :b => b }
|
152
|
+
a[:c] = c
|
153
|
+
|
154
|
+
logger_mock.should_receive(:error).with(/\[Rollbar\] Error reporting message to Rollbar: (nesting of \d+ is too deep|object references itself)/)
|
155
|
+
Rollbar.report_message("Test message with circular extra data", 'debug', a)
|
156
|
+
end
|
157
|
+
|
158
|
+
after(:each) do
|
159
|
+
Rollbar.configure do |config|
|
160
|
+
config.logger = ::Rails.logger
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'payload_destination' do
|
166
|
+
before(:each) do
|
167
|
+
configure
|
168
|
+
Rollbar.configure do |config|
|
169
|
+
config.logger = logger_mock
|
170
|
+
config.filepath = 'test.rollbar'
|
171
|
+
end
|
172
|
+
|
173
|
+
begin
|
174
|
+
foo = bar
|
175
|
+
rescue => e
|
176
|
+
@exception = e
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
let(:logger_mock) { double("Rails.logger").as_null_object }
|
181
|
+
|
182
|
+
it 'should send the payload over the network by default' do
|
183
|
+
logger_mock.should_not_receive(:info).with('[Rollbar] Writing payload to file')
|
184
|
+
logger_mock.should_receive(:info).with('[Rollbar] Sending payload')
|
185
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
186
|
+
Rollbar.report_exception(@exception)
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'should save the payload to a file if set' do
|
190
|
+
logger_mock.should_not_receive(:info).with('[Rollbar] Sending payload')
|
191
|
+
logger_mock.should_receive(:info).with('[Rollbar] Writing payload to file')
|
192
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
193
|
+
|
194
|
+
filepath = ''
|
195
|
+
|
196
|
+
Rollbar.configure do |config|
|
197
|
+
config.write_to_file = true
|
198
|
+
filepath = config.filepath
|
199
|
+
end
|
200
|
+
|
201
|
+
Rollbar.report_exception(@exception)
|
202
|
+
|
203
|
+
File.exist?(filepath).should == true
|
204
|
+
File.read(filepath).should include test_access_token
|
205
|
+
File.delete(filepath)
|
206
|
+
|
207
|
+
Rollbar.configure do |config|
|
208
|
+
config.write_to_file = false
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context 'asynchronous_handling' do
|
214
|
+
before(:each) do
|
215
|
+
configure
|
216
|
+
Rollbar.configure do |config|
|
217
|
+
config.logger = logger_mock
|
218
|
+
end
|
219
|
+
|
220
|
+
begin
|
221
|
+
foo = bar
|
222
|
+
rescue => e
|
223
|
+
@exception = e
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
let(:logger_mock) { double("Rails.logger").as_null_object }
|
228
|
+
|
229
|
+
it 'should send the payload using the default asynchronous handler girl_friday' do
|
230
|
+
logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
|
231
|
+
logger_mock.should_receive(:info).with('[Rollbar] Sending payload')
|
232
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
233
|
+
|
234
|
+
Rollbar.configure do |config|
|
235
|
+
config.use_async = true
|
236
|
+
GirlFriday::WorkQueue::immediate!
|
237
|
+
end
|
238
|
+
|
239
|
+
Rollbar.report_exception(@exception)
|
240
|
+
|
241
|
+
Rollbar.configure do |config|
|
242
|
+
config.use_async = false
|
243
|
+
GirlFriday::WorkQueue::queue!
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'should send the payload using a user-supplied asynchronous handler' do
|
248
|
+
logger_mock.should_receive(:info).with('Custom async handler called')
|
249
|
+
logger_mock.should_receive(:info).with('[Rollbar] Sending payload')
|
250
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
251
|
+
|
252
|
+
Rollbar.configure do |config|
|
253
|
+
config.use_async = true
|
254
|
+
config.async_handler = Proc.new { |payload|
|
255
|
+
logger_mock.info 'Custom async handler called'
|
256
|
+
Rollbar.process_payload(payload)
|
257
|
+
}
|
258
|
+
end
|
259
|
+
|
260
|
+
Rollbar.report_exception(@exception)
|
261
|
+
|
262
|
+
Rollbar.configure do |config|
|
263
|
+
config.use_async = false
|
264
|
+
config.async_handler = Rollbar.method(:default_async_handler)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
context 'message_data' do
|
270
|
+
before(:each) do
|
271
|
+
configure
|
272
|
+
@message_body = "This is a test"
|
273
|
+
@level = 'debug'
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'should build a message' do
|
277
|
+
data = Rollbar.send(:message_data, @message_body, @level, {})
|
278
|
+
data[:body][:message][:body].should == @message_body
|
279
|
+
data[:level].should == @level
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should accept extra_data' do
|
283
|
+
user_id = 123
|
284
|
+
name = "Tester"
|
285
|
+
|
286
|
+
data = Rollbar.send(:message_data, @message_body, 'info',
|
287
|
+
:user_id => user_id, :name => name)
|
288
|
+
|
289
|
+
message = data[:body][:message]
|
290
|
+
message[:body].should == @message_body
|
291
|
+
message[:user_id].should == user_id
|
292
|
+
message[:name].should == name
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context 'exception_data' do
|
297
|
+
before(:each) do
|
298
|
+
configure
|
299
|
+
begin
|
300
|
+
foo = bar
|
301
|
+
rescue => e
|
302
|
+
@exception = e
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'should accept force_level' do
|
307
|
+
level = 'critical'
|
308
|
+
data = Rollbar.send(:exception_data, @exception, level)
|
309
|
+
data[:level].should == level
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'should build valid exception data' do
|
313
|
+
data = Rollbar.send(:exception_data, @exception)
|
314
|
+
|
315
|
+
data[:level].should_not be_nil
|
316
|
+
|
317
|
+
trace = data[:body][:trace]
|
318
|
+
|
319
|
+
frames = trace[:frames]
|
320
|
+
frames.should be_a_kind_of(Array)
|
321
|
+
frames.each do |frame|
|
322
|
+
frame[:filename].should be_a_kind_of(String)
|
323
|
+
frame[:lineno].should be_a_kind_of(Fixnum)
|
324
|
+
if frame[:method]
|
325
|
+
frame[:method].should be_a_kind_of(String)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
# should be NameError, but can be NoMethodError sometimes on rubinius 1.8
|
330
|
+
# http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
|
331
|
+
trace[:exception][:class].should match(/^(NameError|NoMethodError)$/)
|
332
|
+
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
context 'logger' do
|
337
|
+
before(:each) do
|
338
|
+
reset_configuration
|
339
|
+
end
|
340
|
+
|
341
|
+
it 'should have use the Rails logger when configured to do so' do
|
342
|
+
configure
|
343
|
+
Rollbar.send(:logger).should == ::Rails.logger
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'should use the default_logger when no logger is set' do
|
347
|
+
logger = Logger.new(STDERR)
|
348
|
+
Rollbar.configure do |config|
|
349
|
+
config.default_logger = lambda { logger }
|
350
|
+
end
|
351
|
+
Rollbar.send(:logger).should == logger
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'should have a default default_logger' do
|
355
|
+
Rollbar.send(:logger).should_not be_nil
|
356
|
+
end
|
357
|
+
|
358
|
+
after(:each) do
|
359
|
+
reset_configuration
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
context 'build_payload' do
|
364
|
+
it 'should build valid json' do
|
365
|
+
json = Rollbar.send(:build_payload, {:foo => {:bar => "baz"}})
|
366
|
+
hash = MultiJson.load(json)
|
367
|
+
hash["data"]["foo"]["bar"].should == "baz"
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
context 'base_data' do
|
372
|
+
before(:each) { configure }
|
373
|
+
|
374
|
+
it 'should have the correct notifier name' do
|
375
|
+
Rollbar.send(:base_data)[:notifier][:name].should == 'rollbar-gem'
|
376
|
+
end
|
377
|
+
|
378
|
+
it 'should have the correct notifier version' do
|
379
|
+
Rollbar.send(:base_data)[:notifier][:version].should == Rollbar::VERSION
|
380
|
+
end
|
381
|
+
|
382
|
+
it 'should have all the required keys' do
|
383
|
+
data = Rollbar.send(:base_data)
|
384
|
+
data[:timestamp].should_not be_nil
|
385
|
+
data[:environment].should_not be_nil
|
386
|
+
data[:level].should_not be_nil
|
387
|
+
data[:language].should == 'ruby'
|
388
|
+
data[:framework].should match(/^Rails/)
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
context 'server_data' do
|
393
|
+
it 'should have the right hostname' do
|
394
|
+
Rollbar.send(:server_data)[:host] == Socket.gethostname
|
395
|
+
end
|
396
|
+
|
397
|
+
it 'should have root and branch set when configured' do
|
398
|
+
configure
|
399
|
+
Rollbar.configure do |config|
|
400
|
+
config.root = '/path/to/root'
|
401
|
+
config.branch = 'master'
|
402
|
+
end
|
403
|
+
|
404
|
+
data = Rollbar.send(:server_data)
|
405
|
+
data[:root].should == '/path/to/root'
|
406
|
+
data[:branch].should == 'master'
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
# configure with some basic params
|
411
|
+
def configure
|
412
|
+
Rollbar.configure do |config|
|
413
|
+
# special test access token
|
414
|
+
config.access_token = test_access_token
|
415
|
+
config.logger = ::Rails.logger
|
416
|
+
config.environment = ::Rails.env
|
417
|
+
config.root = ::Rails.root
|
418
|
+
config.framework = "Rails: #{::Rails::VERSION::STRING}"
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_access_token
|
423
|
+
'aaaabbbbccccddddeeeeffff00001111'
|
424
|
+
end
|
425
|
+
|
426
|
+
end
|