exceptiontrap 0.0.1.alpha → 0.0.2.alpha
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.
- data/Gemfile +1 -1
- data/exceptiontrap.gemspec +2 -2
- data/generators/exceptiontrap/exceptiontrap_generator.rb +2 -3
- data/generators/exceptiontrap/templates/exceptiontrap.yml +1 -0
- data/lib/exceptiontrap/catcher.rb +0 -2
- data/lib/exceptiontrap/config.rb +16 -41
- data/lib/exceptiontrap/data.rb +62 -59
- data/lib/exceptiontrap/notifier.rb +24 -9
- data/lib/exceptiontrap/rack.rb +3 -3
- data/lib/exceptiontrap/railtie.rb +3 -3
- data/lib/exceptiontrap/version.rb +1 -1
- data/lib/exceptiontrap.rb +7 -7
- data/lib/generators/exceptiontrap/exceptiontrap_generator.rb +9 -9
- data/lib/generators/exceptiontrap/templates/exceptiontrap.yml +1 -0
- metadata +23 -45
data/Gemfile
CHANGED
data/exceptiontrap.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ["tbuehl"]
|
9
9
|
s.email = ["tbuehl@itm-labs.de"]
|
10
10
|
s.homepage = "http://exceptiontrap.com"
|
11
|
-
s.summary = %q{
|
12
|
-
s.description = %q{The
|
11
|
+
s.summary = %q{Exception notifier, used to report your apps exceptions to the exceptiontrap webservice}
|
12
|
+
s.description = %q{Exception notifier. The Gem catches your applications exceptions and sends those to the exceptiontrap webservice hosted at http://exceptiontrap.com}
|
13
13
|
|
14
14
|
s.rubyforge_project = "exceptiontrap"
|
15
15
|
|
data/lib/exceptiontrap/config.rb
CHANGED
@@ -2,73 +2,48 @@ module Exceptiontrap
|
|
2
2
|
class Config
|
3
3
|
class << self
|
4
4
|
DEFAULTS = {
|
5
|
-
:
|
6
|
-
:
|
5
|
+
:enabled_environments => %w(production),
|
6
|
+
:ignored_exceptions => %w(ActiveRecord::RecordNotFound ActionController::RoutingError),
|
7
|
+
:filtered_params => %w(password s3-key),
|
8
|
+
:ssl => false
|
7
9
|
}
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
def load(config_file=nil)
|
11
|
+
def load(config_file = nil)
|
12
12
|
if (config_file && File.file?(config_file))
|
13
13
|
begin
|
14
14
|
config = YAML::load(File.open(config_file))
|
15
|
-
env_config = config[application_environment] || {}
|
16
15
|
|
17
|
-
@api_key = config['api-key']
|
18
|
-
@ssl = config['ssl']
|
19
|
-
@
|
20
|
-
@
|
21
|
-
@
|
16
|
+
@api_key = config['api-key']
|
17
|
+
@ssl = config['ssl']
|
18
|
+
@ignored_exceptions = config['ignoreExceptions']
|
19
|
+
@enabled_environments = config['enabledEnvironments']
|
20
|
+
@filtered_params = config['filterParams']
|
22
21
|
rescue Exception => e
|
23
|
-
raise ConfigException.new("Unable to load configuration #{config_file}
|
22
|
+
raise ConfigException.new("Unable to load configuration #{config_file} : #{e.message}")
|
24
23
|
end
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
28
27
|
def api_key
|
29
|
-
|
28
|
+
@api_key
|
30
29
|
end
|
31
30
|
|
32
31
|
def enabled_environments
|
33
|
-
@
|
32
|
+
@enabled_environments ||= DEFAULTS[:enabled_environments]
|
34
33
|
end
|
35
34
|
|
36
35
|
def ignored_exceptions
|
37
|
-
@
|
36
|
+
@ignored_exceptions ||= DEFAULTS[:ignored_exceptions]
|
38
37
|
end
|
39
38
|
|
40
39
|
def filtered_params
|
41
|
-
@
|
42
|
-
end
|
43
|
-
|
44
|
-
def application_environment
|
45
|
-
ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
|
46
|
-
end
|
47
|
-
|
48
|
-
def should_send_to_api?
|
49
|
-
@enabled ||= DEFAULTS[:disabled_by_default].include?(application_environment) ? false : true
|
50
|
-
end
|
51
|
-
|
52
|
-
def application_root
|
53
|
-
defined?(Rails.root) ? Rails.root : Dir.pwd
|
40
|
+
@filtered_params ||= DEFAULTS[:filtered_params]
|
54
41
|
end
|
55
42
|
|
56
|
-
def
|
43
|
+
def use_ssl?
|
57
44
|
@ssl ||= DEFAULTS[:ssl]
|
58
45
|
end
|
59
46
|
|
60
|
-
def remote_host
|
61
|
-
@remote_host ||= DEFAULTS[:remote_host_http]
|
62
|
-
end
|
63
|
-
|
64
|
-
def remote_port
|
65
|
-
@remote_port ||= ssl? ? 443 : 80
|
66
|
-
end
|
67
|
-
|
68
|
-
def reset
|
69
|
-
@enabled = @ssl = @api_key = nil
|
70
|
-
end
|
71
|
-
|
72
47
|
end
|
73
48
|
end
|
74
49
|
end
|
data/lib/exceptiontrap/data.rb
CHANGED
@@ -1,106 +1,93 @@
|
|
1
1
|
module Exceptiontrap
|
2
2
|
class Data
|
3
3
|
class << self
|
4
|
-
# TODO: Remove the duplication
|
4
|
+
# TODO: Remove the duplication or separate classes
|
5
5
|
# Creates Notification Data for action controller requests (Rails 2)
|
6
6
|
def rails2_data(exception, request, session, response)
|
7
7
|
data = {
|
8
8
|
'notifier' => NOTIFIER_NAME,
|
9
|
-
'api-key' => Config.api_key,
|
10
9
|
'name' => exception.class.name,
|
11
10
|
'message' => exception.message,
|
12
|
-
'
|
13
|
-
'
|
14
|
-
'
|
15
|
-
'
|
16
|
-
'
|
11
|
+
'location' => location(exception),
|
12
|
+
'root' => application_root.to_s,
|
13
|
+
'app_environment' => application_environment,
|
14
|
+
'request_uri' => request.url || REQUEST_URI,
|
15
|
+
'request_params' => clean_params(request.params),
|
16
|
+
'request_session' => clean_params(extrap_session_data(session)),
|
17
17
|
'environment' => clean_params(request.env),
|
18
|
-
'trace' => clean_backtrace(exception
|
19
|
-
'
|
18
|
+
'trace' => clean_backtrace(exception.backtrace),
|
19
|
+
'request_components' => { :controller => request.params[:controller], :action => request.params[:action] }
|
20
20
|
}
|
21
21
|
end
|
22
22
|
|
23
23
|
# Creates Notification Data for rack requests (Rails 3)
|
24
24
|
def rack_data(exception, env)
|
25
|
-
components = {
|
25
|
+
components = {}
|
26
26
|
if env["action_dispatch.request.parameters"] != nil
|
27
|
-
components[:controller] = env[
|
28
|
-
components[:action] = env[
|
29
|
-
components[:module] = env[
|
27
|
+
components[:controller] = env['action_dispatch.request.parameters'][:controller] || nil
|
28
|
+
components[:action] = env['action_dispatch.request.parameters'][:action] || nil
|
29
|
+
components[:module] = env['action_dispatch.request.parameters'][:module] || nil
|
30
30
|
end
|
31
31
|
|
32
32
|
data = {
|
33
33
|
'notifier' => NOTIFIER_NAME,
|
34
|
-
'api-key' => Config.api_key,
|
35
34
|
'name' => exception.class.name,
|
36
35
|
'message' => exception.message,
|
37
|
-
'
|
38
|
-
'
|
39
|
-
'
|
40
|
-
'
|
41
|
-
'
|
36
|
+
'location' => location(exception),
|
37
|
+
'root' => application_root.to_s,
|
38
|
+
'app_environment' => application_environment,
|
39
|
+
'request_uri' => env['REQUEST_URI'],
|
40
|
+
'request_params' => clean_params(env['action_dispatch.request.parameters']),
|
41
|
+
'request_session' => clean_params(extrap_session_data(env['rack.session'])),
|
42
42
|
'environment' => clean_params(env),
|
43
|
-
'trace' => clean_backtrace(exception
|
44
|
-
'
|
43
|
+
'trace' => clean_backtrace(exception.backtrace),
|
44
|
+
'request_components' => components
|
45
45
|
}
|
46
46
|
end
|
47
47
|
|
48
|
-
|
48
|
+
# Cleanup data
|
49
49
|
def clean_params(params)
|
50
50
|
return if params == nil
|
51
|
-
|
52
51
|
params = normalize_data(params)
|
53
52
|
params = filter_params(params)
|
54
|
-
params
|
55
|
-
end
|
56
|
-
|
57
|
-
# Deletes params from env / set in config file
|
58
|
-
def remove_params
|
59
|
-
remove_params = ["rack.request.form_hash", "rack.request.form_vars", "rack.request.form_hash"]
|
60
53
|
end
|
61
54
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
hash.each do |key, value|
|
68
|
-
key_s = key.to_s.dup
|
69
|
-
key_s.sub!("_", "") if key_s[0].chr == "_"
|
70
|
-
key_s.sub!("_", "") if key_s[0].chr == "_"
|
71
|
-
|
72
|
-
if value.respond_to?(:to_hash) # if hash, normalize these too
|
73
|
-
new_hash[key_s] = normalize_data(value.to_hash)
|
74
|
-
else
|
75
|
-
new_hash[key_s] = value.to_s
|
76
|
-
end
|
55
|
+
def clean_backtrace(backtrace)
|
56
|
+
if Rails.respond_to?(:backtrace_cleaner)
|
57
|
+
Rails.backtrace_cleaner.send(:filter, backtrace)
|
58
|
+
else
|
59
|
+
backtrace
|
77
60
|
end
|
61
|
+
end
|
78
62
|
|
79
|
-
|
63
|
+
# Deletes params from env / set in config file
|
64
|
+
def remove_params
|
65
|
+
remove_params = ['rack.request.form_hash', 'rack.request.form_vars']
|
80
66
|
end
|
81
67
|
|
82
68
|
# Replaces parameter values with a string / set in config file
|
83
69
|
def filter_params(params)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
70
|
+
return params unless Config.filtered_params
|
71
|
+
|
72
|
+
params.each do |k, v|
|
73
|
+
if filter_key?(k)
|
74
|
+
params[k] = '[FILTERED]'
|
75
|
+
elsif v.respond_to?(:to_hash)
|
76
|
+
filter_params(params[k])
|
91
77
|
end
|
92
78
|
end
|
79
|
+
|
93
80
|
params
|
94
81
|
end
|
95
82
|
|
96
83
|
# Check, if a key should be filtered
|
97
84
|
def filter_key?(key)
|
98
85
|
Config.filtered_params.any? do |filter|
|
99
|
-
key.to_s.include?(filter.to_s)
|
86
|
+
key.to_s == filter.to_s # key.to_s.include?(filter.to_s)
|
100
87
|
end
|
101
88
|
end
|
102
89
|
|
103
|
-
|
90
|
+
# Retrieve data
|
104
91
|
def extrap_session_data(session)
|
105
92
|
return if session == nil
|
106
93
|
if session.respond_to?(:to_hash)
|
@@ -110,6 +97,10 @@ module Exceptiontrap
|
|
110
97
|
end
|
111
98
|
end
|
112
99
|
|
100
|
+
def location(exception)
|
101
|
+
#TODO: Implement
|
102
|
+
end
|
103
|
+
|
113
104
|
def application_environment
|
114
105
|
ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
|
115
106
|
end
|
@@ -118,12 +109,24 @@ module Exceptiontrap
|
|
118
109
|
defined?(Rails.root) ? Rails.root : Dir.pwd
|
119
110
|
end
|
120
111
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
112
|
+
# Trims first underscore from keys, to prevent "malformed" rails XML-tags
|
113
|
+
def normalize_data(hash)
|
114
|
+
new_hash = {}
|
115
|
+
|
116
|
+
# TODO: Do this nicer
|
117
|
+
hash.each do |key, value|
|
118
|
+
# key_s = key.to_s.dup
|
119
|
+
# key_s.sub!("_", "") if key_s[0].chr == "_"
|
120
|
+
# key_s.sub!("_", "") if key_s[0].chr == "_"
|
121
|
+
|
122
|
+
if value.respond_to?(:to_hash) # if hash, normalize these too
|
123
|
+
new_hash[key] = normalize_data(value.to_hash)
|
124
|
+
else
|
125
|
+
new_hash[key] = value.to_s
|
126
|
+
end
|
126
127
|
end
|
128
|
+
|
129
|
+
new_hash
|
127
130
|
end
|
128
131
|
|
129
132
|
end
|
@@ -2,33 +2,48 @@ module Exceptiontrap
|
|
2
2
|
class Notifier
|
3
3
|
class << self
|
4
4
|
def notify(data)
|
5
|
-
puts
|
5
|
+
puts 'DEBUG: Notify Exception'
|
6
6
|
|
7
7
|
@data = data
|
8
|
-
|
9
|
-
send_problem(
|
8
|
+
serialized_data = { :problem => data }.to_json
|
9
|
+
send_problem(serialized_data) unless ignore_exception?
|
10
10
|
end
|
11
11
|
|
12
|
-
def send_problem(
|
13
|
-
puts
|
12
|
+
def send_problem(serialized_data)
|
13
|
+
puts 'DEBUG: Send Exception'
|
14
14
|
|
15
|
-
url = URI.parse(NOTIFICATION_URL)
|
16
|
-
|
15
|
+
url = URI.parse((Config.use_ssl? ? 'https://' : 'http://') << NOTIFICATION_URL)
|
16
|
+
client = prepare_client(url)
|
17
|
+
|
18
|
+
headers = HEADERS
|
19
|
+
headers['X-Api-Key'] = Config.api_key
|
17
20
|
|
18
21
|
response = begin
|
19
|
-
|
22
|
+
client.post(url.path, serialized_data, headers)
|
20
23
|
rescue TimeoutError => e
|
21
|
-
puts
|
24
|
+
puts 'ERROR: Timeout while contacting Exceptiontrap.'
|
22
25
|
nil
|
23
26
|
rescue Exception => e
|
24
27
|
puts "ERROR: Error on sending: #{e.class} - #{e.message}"
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
31
|
+
private
|
28
32
|
def ignore_exception?
|
29
33
|
Config.ignored_exceptions.include?(@data['name'])
|
30
34
|
end
|
31
35
|
|
36
|
+
def prepare_client(url)
|
37
|
+
if Config.use_ssl?
|
38
|
+
client = Net::HTTP.new(url.host, url.port || 443)
|
39
|
+
client.use_ssl = true
|
40
|
+
client.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
41
|
+
else
|
42
|
+
client = Net::HTTP.new(url.host, url.port || 80)
|
43
|
+
end
|
44
|
+
|
45
|
+
client
|
46
|
+
end
|
32
47
|
end
|
33
48
|
end
|
34
49
|
end
|
data/lib/exceptiontrap/rack.rb
CHANGED
@@ -6,10 +6,10 @@ module Exceptiontrap
|
|
6
6
|
|
7
7
|
def call(env)
|
8
8
|
begin
|
9
|
-
puts
|
9
|
+
puts 'DEBUG: Begin Exceptiontrap::Rack'
|
10
10
|
response = @app.call(env)
|
11
11
|
rescue Exception => raised
|
12
|
-
puts
|
12
|
+
puts 'DEBUG: Raised Exceptiontrap::Rack::Exception'
|
13
13
|
data = Exceptiontrap::Data.rack_data(raised, env)
|
14
14
|
Exceptiontrap::Notifier.notify(data)
|
15
15
|
raise
|
@@ -19,4 +19,4 @@ module Exceptiontrap
|
|
19
19
|
end
|
20
20
|
|
21
21
|
end
|
22
|
-
end
|
22
|
+
end
|
@@ -4,12 +4,12 @@ require 'rails'
|
|
4
4
|
|
5
5
|
module Exceptiontrap
|
6
6
|
class ExceptiontrapRailtie < Rails::Railtie
|
7
|
-
initializer
|
8
|
-
Exceptiontrap::Config.load(File.join(Rails.root,
|
7
|
+
initializer 'exceptiontrap.middleware' do |app|
|
8
|
+
Exceptiontrap::Config.load(File.join(Rails.root, '/config/exceptiontrap.yml'))
|
9
9
|
if Config.enabled_environments.include?(Exceptiontrap::Data.application_environment)
|
10
10
|
# puts "-> Activated Exceptiontrap::Rack for Rails 3 (Railtie)"
|
11
11
|
app.config.middleware.insert_after 'ActionDispatch::ShowExceptions', 'Exceptiontrap::Rack'
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
15
|
-
end
|
15
|
+
end
|
data/lib/exceptiontrap.rb
CHANGED
@@ -12,19 +12,19 @@ require 'exceptiontrap/railtie' if defined?(Rails::Railtie)
|
|
12
12
|
|
13
13
|
# Exceptiontrap
|
14
14
|
module Exceptiontrap
|
15
|
-
API_VERSION =
|
16
|
-
NOTIFIER_NAME =
|
17
|
-
|
18
|
-
|
15
|
+
API_VERSION = '1'
|
16
|
+
NOTIFIER_NAME = 'exceptiontrap-rails'
|
17
|
+
NOTIFICATION_URL = 'alpha.exceptiontrap.com/notifier/api/v1/problems'
|
18
|
+
DEPLOYMENT_URL = 'alpha.exceptiontrap.com/notifier/api/v1/deployments'
|
19
19
|
|
20
20
|
HEADERS = {
|
21
|
-
'Content-type' => '
|
22
|
-
'Accept' => '
|
21
|
+
'Content-type' => 'application/json',
|
22
|
+
'Accept' => 'application/json'
|
23
23
|
}
|
24
24
|
|
25
25
|
# Load for Rails 2.3 (Rack and Exceptiontrap::Catcher)
|
26
26
|
if !defined?(Rails::Railtie) && defined?(Rails.configuration) && Rails.configuration.respond_to?(:middleware)
|
27
|
-
Exceptiontrap::Config.load(File.join(Rails.root,
|
27
|
+
Exceptiontrap::Config.load(File.join(Rails.root, '/config/exceptiontrap.yml'))
|
28
28
|
|
29
29
|
if Config.enabled_environments.include?(Exceptiontrap::Data.application_environment)
|
30
30
|
if defined?(ActionController::Base) && !ActionController::Base.include?(Exceptiontrap::Catcher)
|
@@ -2,27 +2,27 @@ require 'rails/generators'
|
|
2
2
|
|
3
3
|
class ExceptiontrapGenerator < Rails::Generators::Base
|
4
4
|
desc "Run this generator to create the Exceptiontrap config file"
|
5
|
-
|
6
|
-
class_option :api_key, :aliases =>
|
7
|
-
|
5
|
+
|
6
|
+
class_option :api_key, :aliases => '-k', :type => :string, :desc => 'Your Exceptiontrap API key'
|
7
|
+
|
8
8
|
def self.source_root
|
9
9
|
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def install
|
13
13
|
if !options[:api_key]
|
14
|
-
puts
|
14
|
+
puts 'You have to pass --api-key or create config/exceptiontrap.yml manually'
|
15
15
|
exit
|
16
16
|
end
|
17
17
|
#copy_config
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def api_key
|
21
|
-
|
21
|
+
s = "#{options[:api_key]}"
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def copy_config
|
25
|
-
puts
|
25
|
+
puts 'Copying config file to your app'
|
26
26
|
template 'exceptiontrap.yml', 'config/exceptiontrap.yml'
|
27
27
|
end
|
28
28
|
end
|
metadata
CHANGED
@@ -1,35 +1,24 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: exceptiontrap
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2.alpha
|
5
5
|
prerelease: 6
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 1
|
10
|
-
- alpha
|
11
|
-
version: 0.0.1.alpha
|
12
6
|
platform: ruby
|
13
|
-
authors:
|
7
|
+
authors:
|
14
8
|
- tbuehl
|
15
9
|
autorequire:
|
16
10
|
bindir: bin
|
17
11
|
cert_chain: []
|
18
|
-
|
19
|
-
date: 2012-01-04 00:00:00 +01:00
|
20
|
-
default_executable:
|
12
|
+
date: 2012-08-18 00:00:00.000000000 Z
|
21
13
|
dependencies: []
|
22
|
-
|
23
|
-
|
24
|
-
email:
|
14
|
+
description: Exception notifier. The Gem catches your applications exceptions and
|
15
|
+
sends those to the exceptiontrap webservice hosted at http://exceptiontrap.com
|
16
|
+
email:
|
25
17
|
- tbuehl@itm-labs.de
|
26
18
|
executables: []
|
27
|
-
|
28
19
|
extensions: []
|
29
|
-
|
30
20
|
extra_rdoc_files: []
|
31
|
-
|
32
|
-
files:
|
21
|
+
files:
|
33
22
|
- .gitignore
|
34
23
|
- Gemfile
|
35
24
|
- MIT-LICENSE
|
@@ -56,42 +45,31 @@ files:
|
|
56
45
|
- test/exceptiontrap_test.rb
|
57
46
|
- test/test_helper.rb
|
58
47
|
- uninstall.rb
|
59
|
-
has_rdoc: true
|
60
48
|
homepage: http://exceptiontrap.com
|
61
49
|
licenses: []
|
62
|
-
|
63
50
|
post_install_message:
|
64
51
|
rdoc_options: []
|
65
|
-
|
66
|
-
require_paths:
|
52
|
+
require_paths:
|
67
53
|
- lib
|
68
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
55
|
none: false
|
70
|
-
requirements:
|
71
|
-
- -
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
|
74
|
-
|
75
|
-
- 0
|
76
|
-
version: "0"
|
77
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
61
|
none: false
|
79
|
-
requirements:
|
80
|
-
- -
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
hash: 25
|
83
|
-
segments:
|
84
|
-
- 1
|
85
|
-
- 3
|
86
|
-
- 1
|
62
|
+
requirements:
|
63
|
+
- - ! '>'
|
64
|
+
- !ruby/object:Gem::Version
|
87
65
|
version: 1.3.1
|
88
66
|
requirements: []
|
89
|
-
|
90
67
|
rubyforge_project: exceptiontrap
|
91
|
-
rubygems_version: 1.
|
68
|
+
rubygems_version: 1.8.24
|
92
69
|
signing_key:
|
93
70
|
specification_version: 3
|
94
|
-
summary:
|
95
|
-
|
71
|
+
summary: Exception notifier, used to report your apps exceptions to the exceptiontrap
|
72
|
+
webservice
|
73
|
+
test_files:
|
96
74
|
- test/exceptiontrap_test.rb
|
97
75
|
- test/test_helper.rb
|