exceptional 2.0.5 → 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/bin/exceptional CHANGED
@@ -12,25 +12,35 @@ test # Send a test exception to Exceptional.
12
12
  install <api_key> # Create config/exceptional.yml with your api_key. Overrites existing one.
13
13
  USAGE
14
14
  when 'test'
15
- puts "Loading Rails environment."
16
- require(File.join('config', 'boot'))
17
- require(File.join(RAILS_ROOT, 'config', 'environment'))
18
- require "exceptional/integration/tester"
19
- unless Exceptional::Config.api_key.blank?
15
+ if defined?(RAILS_ROOT)
16
+ puts "Loading Rails environment."
17
+ require(File.join('config', 'boot'))
18
+ require(File.join(RAILS_ROOT, 'config', 'environment')) if defined?(RAILS_ROOT)
19
+ require "exceptional/integration/tester"
20
+ else
21
+ require 'json'
22
+ require 'exceptional'
23
+ require "exceptional/integration/tester"
24
+ Exceptional::Config.load('config/exceptional.yml')
25
+ end
26
+ unless Exceptional::Config.api_key.empty?
20
27
  Exceptional::Integration.test
21
- end
28
+ else
29
+ puts 'API key not configured'
30
+ end
22
31
  when 'install'
23
32
  api_key = args[0]
24
33
  if (api_key.nil?)
25
34
  puts 'Missing required paramater <api-key>. Check your app configuration at http://getexceptional.com.'
26
35
  else
27
- unless File.file?('config/environment.rb')
28
- puts "Run this command from the root of your rails application."
36
+ if (defined?(RAILS_ROOT) && !File.file?('config/environment.rb'))
37
+ puts "Run this command from the root of your rails application." and return
29
38
  else
30
- config_file = File.open('config/exceptional.yml', 'w')
31
- config_file.puts("api-key: #{api_key}\n")
32
- config_file.close
33
- puts "Config file written as config/exceptional.yml."
39
+ Dir.mkdir('config') unless File.exists?('config')
34
40
  end
35
- end
41
+ end
42
+ config_file = File.open('config/exceptional.yml', 'w')
43
+ config_file.puts("api-key: #{api_key}\n")
44
+ config_file.close
45
+ puts "Config file written as config/exceptional.yml."
36
46
  end
data/exceptional.gemspec CHANGED
@@ -1,10 +1,10 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |s|
3
3
  s.name = %q{exceptional}
4
- s.version = "2.0.5"
4
+ s.version = "2.0.6"
5
5
  s.authors = ["Contrast"]
6
- s.summary = %q{Exceptional is the core Ruby library for communicating with http://getexceptional.com (hosted error tracking service)}
7
- s.description = %q{Exceptional is the core Ruby library for communicating with http://getexceptional.com (hosted error tracking service). Use it to find out about errors that happen in your live app. It captures lots of helpful information to help you fix the errors.}
6
+ s.summary = %q{ getexceptional.com is a hosted service for tracking errors in your Ruby/Rails/Rack apps }
7
+ s.description = %q{Exceptional is the Ruby gem for communicating with http://getexceptional.com (hosted error tracking service). Use it to find out about errors that happen in your live app. It captures lots of helpful information to help you fix the errors.}
8
8
  s.email = %q{hello@contrast.ie}
9
9
  s.files = Dir['lib/**/*'] + Dir['spec/**/*'] + Dir['spec/**/*'] + Dir['rails/**/*'] + Dir['tasks/**/*'] + Dir['*.rb'] + ["exceptional.gemspec"]
10
10
  s.homepage = %q{http://getexceptional.com/}
data/lib/exceptional.rb CHANGED
@@ -7,12 +7,15 @@ require 'exceptional/config'
7
7
  require 'exceptional/application_environment'
8
8
  require 'exceptional/exception_data'
9
9
  require 'exceptional/controller_exception_data'
10
+ require 'exceptional/rack_exception_data'
10
11
  require 'exceptional/remote'
12
+ require 'exceptional/integration/rack'
11
13
 
12
14
  module Exceptional
15
+
13
16
  PROTOCOL_VERSION = 5
14
- VERSION = '2.0.3'
15
- CLIENT_NAME = 'getexceptional-rails-plugin'
17
+ VERSION = '2.0.6'
18
+ CLIENT_NAME = 'getexceptional-gem'
16
19
 
17
20
  def self.logger
18
21
  ::Exceptional::LogFactory.logger
@@ -2,8 +2,8 @@ require 'digest/md5'
2
2
 
3
3
  module Exceptional
4
4
  class ApplicationEnvironment
5
- def self.to_hash
6
- hash = {
5
+ def self.to_hash(framework)
6
+ {
7
7
  'client' => {
8
8
  'name' => Exceptional::CLIENT_NAME,
9
9
  'version' => Exceptional::VERSION,
@@ -21,11 +21,6 @@ module Exceptional
21
21
  'libraries_loaded' => libraries_loaded
22
22
  }
23
23
  }
24
- hash
25
- end
26
-
27
- def self.framework
28
- defined?(RAILS_ENV) ? "rails" : nil
29
24
  end
30
25
 
31
26
  def self.environment
@@ -7,6 +7,13 @@ module Exceptional
7
7
  Remote.error(data)
8
8
  end
9
9
  end
10
+
11
+ def handle_with_rack(exception, environment, request)
12
+ if Config.should_send_to_api?
13
+ data = RackExceptionData.new(exception, environment, request)
14
+ Remote.error(data)
15
+ end
16
+ end
10
17
 
11
18
  def handle(exception, name=nil)
12
19
  if Config.should_send_to_api?
@@ -16,4 +23,4 @@ module Exceptional
16
23
  end
17
24
  end
18
25
  end
19
- end
26
+ end
@@ -8,6 +8,10 @@ module Exceptional
8
8
  @controller = controller
9
9
  end
10
10
 
11
+ def framework
12
+ "rails"
13
+ end
14
+
11
15
  def extra_stuff
12
16
  return {} if @request.nil?
13
17
  {
@@ -8,7 +8,7 @@ module Exceptional
8
8
  end
9
9
 
10
10
  def to_hash
11
- hash = ::Exceptional::ApplicationEnvironment.to_hash
11
+ hash = ::Exceptional::ApplicationEnvironment.to_hash(framework)
12
12
  hash.merge!({
13
13
  'exception' => {
14
14
  'exception_class' => @exception.class.to_s,
@@ -43,6 +43,10 @@ module Exceptional
43
43
  end
44
44
  end
45
45
  end
46
+
47
+ def framework
48
+ nil
49
+ end
46
50
 
47
51
  def uniqueness_hash
48
52
  return nil if (@exception.backtrace.nil? || @exception.backtrace.empty?)
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'rack'
3
+
4
+ module Rack
5
+ class Exceptional
6
+
7
+ def initialize(app, exceptional_config = "config/exceptional.yml")
8
+ @app = app
9
+ ::Exceptional::Config.load(exceptional_config)
10
+ end
11
+
12
+ def call(env)
13
+ begin
14
+ status, headers, body = @app.call(env)
15
+ rescue Exception => e
16
+ ::Exceptional::Catcher.handle_with_rack(e,env, Rack::Request.new(env))
17
+ raise(e)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ require 'digest/md5'
2
+
3
+ module Exceptional
4
+ class RackExceptionData < ExceptionData
5
+ def initialize(exception, environment, request)
6
+ super(exception)
7
+ @environment = environment
8
+ @request = request
9
+ end
10
+
11
+ def framework
12
+ "rack"
13
+ end
14
+
15
+ def extra_stuff
16
+ return {} if @request.nil?
17
+ {
18
+ 'request' => {
19
+ 'url' => "#{@request.url}",
20
+ 'parameters' => @request.params,
21
+ 'request_method' => @request.request_method.to_s,
22
+ 'remote_ip' => @request.ip,
23
+ 'headers' => @environment.reject{|k,v| !k.match(/^HTTP_/)},
24
+ 'session' => @request.session
25
+ }
26
+ }
27
+ end
28
+ end
29
+ end
@@ -37,10 +37,10 @@ module Exceptional
37
37
  response = client.post(url, data)
38
38
  case response
39
39
  when Net::HTTPSuccess
40
- Exceptional.logger.info('Successful')
40
+ Exceptional.logger.info( "#{url} Successful")
41
41
  return true
42
42
  else
43
- Exceptional.logger.error('Failed')
43
+ Exceptional.logger.error("#{url} - #{response.code} - Failed")
44
44
  end
45
45
  rescue Exception => e
46
46
  Exceptional.logger.error('Problem notifying Exceptional about the error')
@@ -7,7 +7,7 @@ module Exceptional
7
7
  if Config.api_key.blank?
8
8
  raise StartupException, 'API Key must be configured (/config/exceptional.yml)'
9
9
  end
10
- Remote.startup_announce(::Exceptional::ApplicationEnvironment.to_hash)
10
+ Remote.startup_announce(::Exceptional::ApplicationEnvironment.to_hash('rails'))
11
11
  end
12
12
  end
13
13
  end
@@ -118,6 +118,7 @@ describe Exceptional::ControllerExceptionData, 'with request/controller/params'
118
118
  @session_id = '123'
119
119
  end
120
120
  end
121
+
121
122
  request = ActionController::TestRequest.new
122
123
  session = SessionWithInstanceVariables.new
123
124
  request.stub!(:session).and_return(session)
@@ -159,4 +160,6 @@ describe Exceptional::ControllerExceptionData, 'with request/controller/params'
159
160
  data = Exceptional::ControllerExceptionData.new(myException)
160
161
  data.uniqueness_hash.should == nil
161
162
  end
163
+
164
+
162
165
  end
@@ -0,0 +1,87 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'digest/md5'
3
+
4
+ describe Exceptional::RackExceptionData do
5
+
6
+ class Exceptional::FunkyError < StandardError
7
+ def backtrace
8
+ 'backtrace'
9
+ end
10
+ end
11
+
12
+ before :each do
13
+ app = lambda { |env| [200, {'Content-Type'=>'text/plain'}, 'Hello World']}
14
+
15
+ @env = {
16
+ "HTTP_HOST" =>"localhost:9292",
17
+ "HTTP_ACCEPT" =>"*/*",
18
+ "SERVER_NAME" =>"localhost",
19
+ "REQUEST_PATH" =>"/",
20
+ "rack.url_scheme" =>"http",
21
+ "HTTP_USER_AGENT" =>"curl/7.19.6 (i386-apple-darwin9.8.0) libcurl/7.19.6 zlib/1.2.3",
22
+ "REMOTE_HOST" =>"testing.com",
23
+ "rack.errors" => StringIO.new,
24
+ "SERVER_PROTOCOL" =>"HTTP/1.1",
25
+ "rack.version" =>[1, 1],
26
+ "rack.run_once" =>false,
27
+ "SERVER_SOFTWARE" =>"WEBrick/1.3.1 (Ruby/1.8.7/2009-06-12)",
28
+ "REMOTE_ADDR" =>"127.0.0.1",
29
+ "PATH_INFO" => "/",
30
+ "SCRIPT_NAME" =>"",
31
+ "HTTP_VERSION" =>"HTTP/1.1",
32
+ "rack.multithread" =>true,
33
+ "rack.multiprocess" =>false,
34
+ "REQUEST_URI" =>"http://localhost:9292/",
35
+ "SERVER_PORT" =>"9292",
36
+ "REQUEST_METHOD" =>"GET",
37
+ "rack.input" => StringIO.new,
38
+ "QUERY_STRING" =>"cockle=shell&bay=cool",
39
+ "GATEWAY_INTERFACE" =>"CGI/1.1"
40
+ }
41
+
42
+ error = Exceptional::FunkyError.new('some message')
43
+ request = Rack::Request.new(@env)
44
+ @data = Exceptional::RackExceptionData.new(error, @env, request)
45
+ end
46
+
47
+ it "capture exception details" do
48
+ error_hash = @data.to_hash['exception']
49
+ error_hash['exception_class'].should == 'Exceptional::FunkyError'
50
+ error_hash['message'].should == 'some message'
51
+ error_hash['backtrace'].should == 'backtrace'
52
+ error_hash['occurred_at'].should == Time.now.strftime("%Y%m%d %H:%M:%S %Z")
53
+ end
54
+
55
+ it "should capture request details" do
56
+ request_hash = @data.to_hash['request']
57
+ request_hash['url'].should == 'http://localhost:9292/?cockle=shell&bay=cool'
58
+ request_hash['parameters'].should == {"cockle"=>"shell", "bay"=>"cool"}
59
+ request_hash['request_method'].should == 'GET'
60
+ request_hash['remote_ip'].should == '127.0.0.1'
61
+ request_hash['headers'].should == {"HTTP_HOST"=>"localhost:9292", "HTTP_ACCEPT"=>"*/*", "HTTP_USER_AGENT"=>"curl/7.19.6 (i386-apple-darwin9.8.0) libcurl/7.19.6 zlib/1.2.3", "HTTP_VERSION"=>"HTTP/1.1"}
62
+ request_hash['session'].should == {}
63
+ end
64
+
65
+ it "should capture client detais" do
66
+ client_hash = @data.to_hash['client']
67
+ client_hash['name'].should == Exceptional::CLIENT_NAME
68
+ client_hash['version'].should == Exceptional::VERSION
69
+ client_hash['protocol_version'].should == Exceptional::PROTOCOL_VERSION
70
+ end
71
+
72
+ it "should captire application environment" do
73
+ env_hash = @data.to_hash['application_environment']
74
+ env_hash['env'].should_not be_empty #execution dependent
75
+ env_hash['libraries_loaded'].should_not be_empty #execution dependent
76
+ env_hash['language'].should == 'ruby' #execution dependent
77
+
78
+ env_hash['language_version'].should_not be_empty #execution dependent
79
+ env_hash['environment'].should == 'test'
80
+ env_hash['application_root_directory'].should_not be_empty
81
+ env_hash['run_as_user'].should_not be_empty
82
+ env_hash['host'].should_not be_empty
83
+
84
+ env_hash['framework'].should == 'rack'
85
+ end
86
+
87
+ end
@@ -0,0 +1,21 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'rack/mock'
3
+
4
+ class ExceptionalTestError < StandardError
5
+ end
6
+
7
+ describe Rack::Exceptional do
8
+
9
+ before(:each) do
10
+ Exceptional::Config.should_receive(:load)
11
+ @error = ExceptionalTestError.new
12
+ @app = lambda { |env| raise @error, 'Whoops!' }
13
+ @env = env = Rack::MockRequest.env_for("/foo")
14
+ end
15
+
16
+ it 're-raises errors caught in the middleware' do
17
+ rr = Rack::Exceptional.new(@app)
18
+ Exceptional::Catcher.should_receive(:handle_with_rack)
19
+ lambda { rr.call(@env)}.should raise_error(ExceptionalTestError)
20
+ end
21
+ end
@@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), '..', 'lib', 'exceptional', 'integrati
3
3
 
4
4
  describe Exceptional, 'version number' do
5
5
  it "be available proramatically" do
6
- Exceptional::VERSION.should == '2.0.3'
6
+ Exceptional::VERSION.should == '2.0.6'
7
7
  end
8
8
  end
9
9
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exceptional
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.5
4
+ version: 2.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Contrast
@@ -9,11 +9,11 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-12 00:00:00 +00:00
12
+ date: 2010-01-26 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
16
- description: Exceptional is the core Ruby library for communicating with http://getexceptional.com (hosted error tracking service). Use it to find out about errors that happen in your live app. It captures lots of helpful information to help you fix the errors.
16
+ description: Exceptional is the Ruby gem for communicating with http://getexceptional.com (hosted error tracking service). Use it to find out about errors that happen in your live app. It captures lots of helpful information to help you fix the errors.
17
17
  email: hello@contrast.ie
18
18
  executables:
19
19
  - exceptional
@@ -27,9 +27,11 @@ files:
27
27
  - lib/exceptional/config.rb
28
28
  - lib/exceptional/controller_exception_data.rb
29
29
  - lib/exceptional/exception_data.rb
30
+ - lib/exceptional/integration/rack.rb
30
31
  - lib/exceptional/integration/rails.rb
31
32
  - lib/exceptional/integration/tester.rb
32
33
  - lib/exceptional/log_factory.rb
34
+ - lib/exceptional/rack_exception_data.rb
33
35
  - lib/exceptional/remote.rb
34
36
  - lib/exceptional/startup.rb
35
37
  - lib/exceptional.rb
@@ -37,12 +39,14 @@ files:
37
39
  - spec/exceptional/catcher_spec.rb
38
40
  - spec/exceptional/config_spec.rb
39
41
  - spec/exceptional/exception_data_spec.rb
42
+ - spec/exceptional/rack_exception_data_spec.rb
40
43
  - spec/exceptional/remote_spec.rb
41
44
  - spec/exceptional/startup_spec.rb
42
45
  - spec/exceptional_rescue_spec.rb
43
46
  - spec/fixtures/exceptional.yml
44
47
  - spec/fixtures/exceptional_old.yml
45
48
  - spec/ginger_scenarios.rb
49
+ - spec/rack_integration_spec.rb
46
50
  - spec/rails_integration_spec.rb
47
51
  - spec/spec_helper.rb
48
52
  - spec/standalone_spec.rb
@@ -78,6 +82,6 @@ rubyforge_project: exceptional
78
82
  rubygems_version: 1.3.5
79
83
  signing_key:
80
84
  specification_version: 3
81
- summary: Exceptional is the core Ruby library for communicating with http://getexceptional.com (hosted error tracking service)
85
+ summary: getexceptional.com is a hosted service for tracking errors in your Ruby/Rails/Rack apps
82
86
  test_files: []
83
87