failbot_rails 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.md +65 -0
  2. data/failbot_rails.gemspec +21 -0
  3. data/lib/failbot_rails.rb +146 -0
  4. metadata +64 -0
@@ -0,0 +1,65 @@
1
+ # failbot_rails
2
+
3
+ Configures a Rails application to report exceptions to [Haystack][] using the
4
+ [Failbot][] library.
5
+
6
+ [Haystack]: https://haystack.githubapp.com
7
+ [Failbot]: https://github.com/github/failbot
8
+
9
+ ## Installation
10
+
11
+ Add it to the app's Gemfile manifest. The gem is publicly available but **keep
12
+ this repository private.**
13
+
14
+ ```ruby
15
+ gem "failbot_rails", "~>0.2"
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ Require `failbot_rails` at the very top of `config/application.rb` right after
21
+ loading `boot.rb`:
22
+
23
+ ```ruby
24
+ require File.expand_path('../boot', __FILE__)
25
+
26
+ # report exceptions to Haystack using Failbot
27
+ require "failbot_rails"
28
+ FailbotRails.setup("my_app")
29
+ ```
30
+
31
+ Every library, script or unicorn that loads the Rails environment are now setup
32
+ to automatically report all exceptions to Haystack.
33
+
34
+ ### `failbot_context`
35
+
36
+ The exception context is automatically populated with request metadata including
37
+ the URL, method, params, etc. It can be augmented by defining a` failbot_context`
38
+ method on `ApplicationController`:
39
+
40
+ ```ruby
41
+ def failbot_context
42
+ {:repo => current_repository.name_with_owner}
43
+ end
44
+ ```
45
+
46
+ ### `failbot(exception, context={})`
47
+
48
+ Use the `failbot` helper anywhere in controllers, views or helpers to manually
49
+ rescue and report an exception. Often used in "graceful degradation" situations.
50
+ **Often risky and error prone but sometimes worth it. Consider carefully before
51
+ using.**
52
+
53
+ ```ruby
54
+ def load_tree
55
+ current_repository.tree(params[:tree])
56
+ rescue TreeCorruptError
57
+ failbot($!)
58
+ nil
59
+ end
60
+ ```
61
+
62
+ ## Contributing
63
+
64
+ The failbot_rails project follows the open source contribution model and is
65
+ maintained by @sr. Open a pull request and wait for a :+1:
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "failbot_rails"
5
+ s.version = "0.3.1"
6
+ s.platform = Gem::Platform::RUBY
7
+ s.authors = %w[@sr]
8
+ s.email = ["sr@github.com"]
9
+ s.homepage = "https://github.com/github/failbot_rails#readme"
10
+ s.summary = "Glue code for using Failbot in a Rails app"
11
+ s.description = s.summary
12
+
13
+ s.required_rubygems_version = ">= 1.3.6"
14
+
15
+ s.add_runtime_dependency "failbot", "~>0.9.0"
16
+
17
+ s.files = `git ls-files`.split("\n") - %w[Gemfile Gemfile.lock]
18
+ s.test_files = `git ls-files -- test`.split("\n").select { |f| f =~ /_test.rb$/ }
19
+ s.executables = `git ls-files -- bin`.split("\n").map { |f| File.basename(f) }
20
+ s.require_paths = %w[lib]
21
+ end
@@ -0,0 +1,146 @@
1
+ require "failbot"
2
+ require "failbot/middleware"
3
+
4
+ require "rails"
5
+ require "rails/railtie"
6
+ require "active_support/concern"
7
+
8
+ module FailbotRails
9
+ def self.setup(app_name)
10
+ if _setup
11
+ fail "FailbotRails already setup"
12
+ end
13
+
14
+ if !app_name.respond_to?(:to_str) || app_name.to_str.empty?
15
+ raise ArgumentError, "app_name argument is required"
16
+ end
17
+
18
+ settings = ENV.to_hash
19
+
20
+ # sensible defaults
21
+ if Rails.env.development? || Rails.env.test?
22
+ settings["FAILBOT_BACKEND"] ||= "memory"
23
+
24
+ if !settings.key?("FAILBOT_RAISE")
25
+ settings["FAILBOT_RAISE"] = "1"
26
+ end
27
+ end
28
+
29
+ Failbot.setup(settings, {:app => app_name.to_str})
30
+ Failbot.install_unhandled_exception_hook!
31
+
32
+ @_setup = true
33
+ end
34
+
35
+ class << self
36
+ attr_reader :_setup
37
+ end
38
+
39
+ class Engine < Rails::Railtie
40
+ initializer "failbot_rails.assert_setup" do |app|
41
+ app.config.before_initialize do
42
+ if !::FailbotRails._setup
43
+ fail "FailbotRails must be setup like so: FailbotRails.setup(\"my_app\")"
44
+ end
45
+ end
46
+ end
47
+
48
+ initializer "failbot_rails.install_middleware" do |app|
49
+ app.middleware.insert_after \
50
+ ::ActionDispatch::DebugExceptions,
51
+ ::FailbotRails::Middleware
52
+ end
53
+
54
+ initializer "failbot_rails.install_action_controller_utilities" do |app|
55
+ app.config.to_prepare do
56
+ ActiveSupport.on_load(:action_controller) do
57
+ include ::FailbotRails::ActionControllerUtilities
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ class Middleware < ::Failbot::Rescuer
64
+ def initialize(app)
65
+ @app = app
66
+ end
67
+
68
+ def call(env)
69
+ request = Rack::Request.new(env)
70
+ @app.call(env)
71
+ rescue Exception
72
+ context = {
73
+ :method => request.request_method,
74
+ :url => request.url,
75
+ :user_agent => request.env["HTTP_USER_AGENT"],
76
+ :params => request.params,
77
+ :session => (request.session.to_hash rescue nil),
78
+ :referrer => request.referrer,
79
+ :remote_ip => request.ip,
80
+ }
81
+ Failbot.report($!, ::FailbotRails._failbot_safe_context(context))
82
+ raise
83
+ end
84
+ end
85
+
86
+ def self._failbot_safe_context(context)
87
+ new_context = {}.merge(context)
88
+ filters = Rails.application.config.filter_parameters
89
+ filter = ActionDispatch::Http::ParameterFilter.new(filters)
90
+
91
+ if new_context.key?(:params)
92
+ new_context[:params] = filter.filter(new_context[:params])
93
+ end
94
+
95
+ new_context
96
+ end
97
+
98
+ module ActionControllerUtilities
99
+ extend ActiveSupport::Concern
100
+
101
+ included do
102
+ # reset context before populating it with rails-specific info
103
+ before_filter :_failbot_rails
104
+
105
+ helper_method :failbot
106
+ end
107
+
108
+ private
109
+
110
+ def failbot(e, context={})
111
+ if e.kind_of?(ActionView::TemplateError) && e.respond_to?(:original_exception)
112
+ # exceptions raised from views are wrapped in TemplateError. This is the
113
+ # most annoying thing ever.
114
+ e = e.original_exception
115
+ end
116
+
117
+ if e.respond_to?(:info) && e.info.is_a?(Hash)
118
+ context = e.info.merge(context || {})
119
+ end
120
+
121
+ Failbot.report(e, ::FailbotRails._failbot_safe_context(context))
122
+ end
123
+
124
+ def _failbot_rails
125
+ # clear context before every request
126
+ Failbot.reset!
127
+
128
+ context = {
129
+ :controller => params[:controller],
130
+ :action => params[:action],
131
+ :user => lambda {
132
+ respond_to?(:current_user) &&
133
+ current_user.respond_to?(:login) &&
134
+ current_user.login
135
+ },
136
+ }
137
+
138
+ # allow overriding context by defining ApplicationController#failbot_context
139
+ if respond_to?(:failbot_context) && failbot_context.respond_to?(:to_hash)
140
+ context.merge!(failbot_context.to_hash)
141
+ end
142
+
143
+ Failbot.push(::FailbotRails._failbot_safe_context(context))
144
+ end
145
+ end
146
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: failbot_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - ! '@sr'
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: failbot
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.9.0
30
+ description: Glue code for using Failbot in a Rails app
31
+ email:
32
+ - sr@github.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - README.md
38
+ - failbot_rails.gemspec
39
+ - lib/failbot_rails.rb
40
+ homepage: https://github.com/github/failbot_rails#readme
41
+ licenses: []
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: 1.3.6
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 1.8.23
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Glue code for using Failbot in a Rails app
64
+ test_files: []