failbot_rails 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []