sfalma 0.7

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 (50) hide show
  1. data/bin/sfalma +76 -0
  2. data/init.rb +27 -0
  3. data/install.rb +19 -0
  4. data/lib/sfalma/alert_data.rb +15 -0
  5. data/lib/sfalma/application_environment.rb +79 -0
  6. data/lib/sfalma/catcher.rb +26 -0
  7. data/lib/sfalma/config.rb +93 -0
  8. data/lib/sfalma/controller_exception_data.rb +69 -0
  9. data/lib/sfalma/exception_data.rb +146 -0
  10. data/lib/sfalma/integration/alerter.rb +11 -0
  11. data/lib/sfalma/integration/dj.rb +12 -0
  12. data/lib/sfalma/integration/rack.rb +28 -0
  13. data/lib/sfalma/integration/rack_rails.rb +26 -0
  14. data/lib/sfalma/integration/rails.rb +27 -0
  15. data/lib/sfalma/integration/sinatra.rb +6 -0
  16. data/lib/sfalma/integration/tester.rb +20 -0
  17. data/lib/sfalma/log_factory.rb +39 -0
  18. data/lib/sfalma/monkeypatches.rb +10 -0
  19. data/lib/sfalma/rack_exception_data.rb +29 -0
  20. data/lib/sfalma/railtie.rb +20 -0
  21. data/lib/sfalma/remote.rb +59 -0
  22. data/lib/sfalma/startup.rb +14 -0
  23. data/lib/sfalma/vcs.rb +45 -0
  24. data/lib/sfalma/version.rb +3 -0
  25. data/lib/sfalma.rb +71 -0
  26. data/lib/tasks/sfalma_tasks.rake +11 -0
  27. data/rails/init.rb +1 -0
  28. data/sfalma.gemspec +18 -0
  29. data/spec/bin/ginger +54 -0
  30. data/spec/dj_integration_spec.rb +29 -0
  31. data/spec/fixtures/favicon.png +0 -0
  32. data/spec/fixtures/sfalma.yml +10 -0
  33. data/spec/fixtures/sfalma_disabled.yml +4 -0
  34. data/spec/ginger_scenarios.rb +33 -0
  35. data/spec/rack_integration_spec.rb +21 -0
  36. data/spec/rails_integration_spec.rb +95 -0
  37. data/spec/rails_rack_integration_spec.rb +29 -0
  38. data/spec/sfalma/alert_exception_data_spec.rb +11 -0
  39. data/spec/sfalma/catcher_spec.rb +13 -0
  40. data/spec/sfalma/config_spec.rb +64 -0
  41. data/spec/sfalma/controller_exception_data_spec.rb +26 -0
  42. data/spec/sfalma/exception_data_spec.rb +198 -0
  43. data/spec/sfalma/monkeypatches_spec.rb +11 -0
  44. data/spec/sfalma/rack_exception_data_spec.rb +87 -0
  45. data/spec/sfalma/remote_spec.rb +31 -0
  46. data/spec/sfalma/startup_spec.rb +15 -0
  47. data/spec/sfalma_rescue_spec.rb +74 -0
  48. data/spec/spec_helper.rb +23 -0
  49. data/spec/standalone_spec.rb +9 -0
  50. metadata +111 -0
@@ -0,0 +1,20 @@
1
+ module Sfalma
2
+ module Integration
3
+ class SfalmaTestException <StandardError;
4
+ end
5
+
6
+ def self.test
7
+ begin
8
+ raise SfalmaTestException.new, 'Test exception from Rails'
9
+ rescue Exception => e
10
+ unless Sfalma::Remote.error(Sfalma::ExceptionData.new(e, "Test Exception"))
11
+ puts "Problem sending exception to Sfalma. Check your API key."
12
+ else
13
+ puts "We got one! Head to http://www.sfalma.com/login to see the error!"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+
@@ -0,0 +1,39 @@
1
+ require 'logger'
2
+
3
+ module Sfalma
4
+ class LogFactory
5
+ def self.logger
6
+ @logger ||= create_logger_with_fallback
7
+ end
8
+
9
+ private
10
+ def self.create_logger_with_fallback
11
+ begin
12
+ log_dir = File.join(Config.application_root, 'log')
13
+ Dir.mkdir(log_dir) unless File.directory?(log_dir)
14
+ log_path = File.join(log_dir, "/sfalma.log")
15
+ log = Logger.new(log_path)
16
+ log.level = Logger::INFO
17
+ def log.format_message(severity, timestamp, progname, msg)
18
+ "[#{severity.upcase}] (#{[Kernel.caller[2].split('/').last]}) #{timestamp.utc.to_s} - #{msg2str(msg).gsub(/\n/, '').lstrip}\n"
19
+ end
20
+ def log.msg2str(msg)
21
+ case msg
22
+ when ::String
23
+ msg
24
+ when ::Exception
25
+ "#{ msg.message } (#{ msg.class }): " <<
26
+ (msg.backtrace || []).join(" | ")
27
+ else
28
+ msg.inspect
29
+ end
30
+ end
31
+ log
32
+ rescue
33
+ return Rails.logger if defined?(Rails) && defined?(Rails.logger)
34
+ return RAILS_DEFAULT_LOGGER if defined?(RAILS_DEFAULT_LOGGER)
35
+ return Logger.new(STDERR)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,10 @@
1
+ class Regexp
2
+ def to_json(options = {})
3
+ "\"#{self.to_s}\""
4
+ end
5
+ end
6
+ class Fixnum
7
+ def to_json(options = {})
8
+ to_s
9
+ end
10
+ end
@@ -0,0 +1,29 @@
1
+ require 'digest/md5'
2
+
3
+ module Sfalma
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' => extract_http_headers(@environment),
24
+ 'session' => self.class.sanitize_session(@request)
25
+ }
26
+ }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ require 'sfalma'
2
+ require 'rails'
3
+
4
+ module Sfalma
5
+ class Railtie < Rails::Railtie
6
+
7
+ initializer "sfalma.middleware" do |app|
8
+
9
+ config_file = File.join(Rails.root, "/config/sfalma.yml")
10
+ Sfalma::Config.load config_file if File.exist?(config_file)
11
+ # On Heroku config is loaded via the ENV so no need to load it from the file
12
+
13
+ if Sfalma::Config.should_send_to_api?
14
+ Sfalma.logger.info("Loading Sfalma #{Sfalma::VERSION} for #{Rails::VERSION::STRING}")
15
+ app.config.middleware.use "Rack::RailsSfalma"
16
+ Sfalma::Startup.announce
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,59 @@
1
+ require 'cgi'
2
+ require 'net/http'
3
+ require 'net/https'
4
+ require 'digest/md5'
5
+ require 'uri'
6
+
7
+ module Sfalma
8
+ class Remote
9
+ class << self
10
+ def startup_announce(startup_data)
11
+ data = startup_data.to_json
12
+ hash_param = "&hash=#{Digest::MD5.new(data).hexdigest}"
13
+ url = "/api/announcements?protocol_version=#{::Sfalma::PROTOCOL_VERSION}#{hash_param}"
14
+ call_remote(url, data)
15
+ end
16
+
17
+ def error(exception_data)
18
+ uniqueness_hash = exception_data.uniqueness_hash
19
+ #require 'net/http'
20
+ #require 'uri'
21
+ #Net::HTTP.post_form(URI.parse('http://www.postbin.org/pelg4f'), {:data=> exception_data.to_json})
22
+ hash_param = uniqueness_hash.nil? ? nil: "&hash=#{uniqueness_hash}"
23
+ url = "/api/errors?protocol_version=#{::Sfalma::PROTOCOL_VERSION}#{hash_param}"
24
+ call_remote(url, exception_data.to_json)
25
+ end
26
+
27
+ def call_remote(url, data)
28
+ config = Sfalma::Config
29
+ optional_proxy = Net::HTTP::Proxy(config.http_proxy_host,
30
+ config.http_proxy_port,
31
+ config.http_proxy_username,
32
+ config.http_proxy_password)
33
+ client = optional_proxy.new(config.remote_host, config.remote_port)
34
+
35
+ client.open_timeout = config.http_open_timeout
36
+ client.read_timeout = config.http_read_timeout
37
+ client.use_ssl = config.ssl?
38
+ client.verify_mode = OpenSSL::SSL::VERIFY_NONE if config.ssl?
39
+ begin
40
+ headers = { "X-Sfalma-Api-Key" => ::Sfalma::Config.api_key }
41
+ data.gsub!('&','@@@')
42
+ response = client.post(url, "data=#{data}", headers)
43
+ case response
44
+ when Net::HTTPSuccess
45
+ Sfalma.logger.info( "#{url} - #{response.message}")
46
+ return true
47
+ else
48
+ Sfalma.logger.error("#{url} - #{response.code} - #{response.message}")
49
+ end
50
+ rescue Exception => e
51
+ Sfalma.logger.error('Problem notifying Sfalma about the error')
52
+ Sfalma.logger.error('You should better send us an email')
53
+ Sfalma.logger.error(e)
54
+ end
55
+ nil
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,14 @@
1
+ module Sfalma
2
+ class StartupException < StandardError;
3
+ end
4
+ class Startup
5
+ class << self
6
+ def announce
7
+ if Config.api_key.blank?
8
+ raise StartupException, 'API Key must be configured (/config/sfalma.yml)'
9
+ end
10
+ Remote.startup_announce(::Sfalma::ApplicationEnvironment.to_hash('rails'))
11
+ end
12
+ end
13
+ end
14
+ end
data/lib/sfalma/vcs.rb ADDED
@@ -0,0 +1,45 @@
1
+ # If you read the source code you do the right thing! Read code and reach mastery!
2
+ # If you wonder what this is be prepared for a very neat feature! More to come soon!
3
+ module Sfalma
4
+ class VCS
5
+ def init
6
+ end
7
+
8
+ def to_hash
9
+ vcs = Sfalma::vcs
10
+ if vcs.size > 1
11
+ return {}
12
+ else
13
+ return {
14
+ 'vcs' => {
15
+ 'type' => Sfalma::vcs
16
+ }
17
+ }
18
+ end
19
+ end
20
+
21
+ def blame(filename)
22
+ end
23
+
24
+ def git(filename)
25
+ end
26
+
27
+ def hg(filename)
28
+ end
29
+
30
+ def svn(filename)
31
+ end
32
+
33
+ end
34
+ end
35
+
36
+ # 55b250f03f1ec3c83679f9f9a158cbe1da3c9796 7 12 1
37
+ # author Panagiotis Papadopoulos
38
+ # author-mail <panosjee@gmail.com>
39
+ # author-time 1294941201
40
+ # author-tz +0200
41
+ # committer Panagiotis Papadopoulos
42
+ # committer-mail <panosjee@gmail.com>
43
+ # committer-time 1294941201
44
+ # committer-tz +0200
45
+ # summary first commit
@@ -0,0 +1,3 @@
1
+ module Sfalma
2
+ VERSION = '0.7'
3
+ end
data/lib/sfalma.rb ADDED
@@ -0,0 +1,71 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'sfalma/monkeypatches'
4
+ require 'sfalma/catcher'
5
+ require 'sfalma/startup'
6
+ require 'sfalma/log_factory'
7
+ require 'sfalma/config'
8
+ require 'sfalma/application_environment'
9
+ require 'sfalma/exception_data'
10
+ require 'sfalma/controller_exception_data'
11
+ require 'sfalma/rack_exception_data'
12
+ require 'sfalma/alert_data'
13
+ require 'sfalma/remote'
14
+ require 'sfalma/integration/rack'
15
+ require 'sfalma/integration/rack_rails'
16
+ require 'sfalma/integration/alerter'
17
+ require 'sfalma/version'
18
+ require 'sfalma/vcs'
19
+
20
+ require 'sfalma/railtie' if defined?(Rails::Railtie)
21
+
22
+ module Sfalma
23
+ PROTOCOL_VERSION = 1
24
+ CLIENT_NAME = 'sfalma-gem'
25
+ ENVIRONMENT_FILTER = []
26
+
27
+ def self.logger
28
+ ::Sfalma::LogFactory.logger
29
+ end
30
+
31
+ def self.configure(api_key)
32
+ Sfalma::Config.api_key = api_key
33
+ end
34
+
35
+ def self.handle(exception, name=nil)
36
+ Sfalma::Catcher.handle(exception, name)
37
+ end
38
+
39
+ def self.rescue(name=nil, context=nil, &block)
40
+ begin
41
+ self.context(context) unless context.nil?
42
+ block.call
43
+ rescue Exception => e
44
+ Sfalma::Catcher.handle(e,name)
45
+ ensure
46
+ self.clear!
47
+ end
48
+ end
49
+
50
+ def self.rescue_and_reraise(name=nil, context=nil, &block)
51
+ begin
52
+ self.context(context) unless context.nil?
53
+ block.call
54
+ rescue Exception => e
55
+ Sfalma::Catcher.handle(e,name)
56
+ raise(e)
57
+ ensure
58
+ self.clear!
59
+ end
60
+ end
61
+
62
+ def self.clear!
63
+ Thread.current[:sfalma_context] = nil
64
+ end
65
+
66
+ def self.context(hash = {})
67
+ Thread.current[:sfalma_context] ||= {}
68
+ Thread.current[:sfalma_context].merge!(hash)
69
+ self
70
+ end
71
+ end
@@ -0,0 +1,11 @@
1
+ namespace :sfalma do
2
+ desc 'Send a test exception to Sfalma.'
3
+ task :test => :environment do
4
+ unless Sfalma::Config.api_key.blank?
5
+ puts "Sending test exception to Sfalma."
6
+ require "sfalma/integration/tester"
7
+ Sfalma::Integration.test
8
+ puts "Done. You can sleep in peace."
9
+ end
10
+ end
11
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__) , '../init.rb')
data/sfalma.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/sfalma/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = %q{sfalma}
6
+ gem.version = Sfalma::VERSION
7
+ gem.authors = ["Sfalma"]
8
+ gem.summary = %q{ sfalma.com is a cloud-based error tracker with a social twist with a focus on mobile apps }
9
+ gem.description = %q{Sfalma is the Ruby gem for communicating with http://sfalma.com (hosted error tracking service). Use it to find out about errors that happen in your web or mobile app. }
10
+ gem.email = %q{info@sfalma.com}
11
+ gem.files = Dir['lib/**/*'] + Dir['spec/**/*'] + Dir['spec/**/*'] + Dir['rails/**/*'] + Dir['tasks/**/*'] + Dir['*.rb'] + ["sfalma.gemspec"]
12
+ gem.homepage = %q{http://sfalma.com/}
13
+ gem.require_paths = ["lib"]
14
+ gem.executables << 'sfalma'
15
+ gem.rubyforge_project = %q{sfalma}
16
+ gem.requirements << "json_pure, json-jruby or json gem required"
17
+ gem.add_dependency 'rack'
18
+ end
data/spec/bin/ginger ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ begin
5
+ require 'ginger'
6
+ rescue LoadError
7
+ puts <<-INSTALL_GINGER
8
+ Install ginger to test plugin against multiple environments:
9
+
10
+ gem install ginger
11
+
12
+ More details: http://github.com/freelancing-god/ginger
13
+ INSTALL_GINGER
14
+ exit 0
15
+ end
16
+
17
+ require 'rake'
18
+
19
+ if ARGV.length == 0
20
+ puts <<-USAGE
21
+ ginger #{Ginger::Version::String}
22
+ Use ginger to run specs for each scenario defined. Scenarios must be set out in
23
+ a file called ginger_scenarios.rb wherever this tool is run. Once they're
24
+ defined, then you can run this tool and provide the rake task that would
25
+ normally be called.
26
+
27
+ Examples:
28
+ ginger spec
29
+ ginger test
30
+ ginger spec:models
31
+ USAGE
32
+ exit 0
33
+ end
34
+
35
+ file_path = File.join Dir.pwd, ".ginger"
36
+
37
+ File.delete(file_path) if File.exists?(file_path)
38
+
39
+ scenarios = Ginger::Configuration.instance.scenarios
40
+ puts "No Ginger Scenarios defined" if scenarios.empty?
41
+
42
+ scenarios.each_with_index do |scenario, index|
43
+ puts <<-SCENARIO
44
+
45
+ -------------------
46
+ Ginger Scenario: #{scenario.name || index+1}
47
+ -------------------
48
+ SCENARIO
49
+
50
+ File.open('.ginger', 'w') { |f| f.write index.to_s }
51
+ system("rake #{ARGV.join(" ")}") || system("rake.bat #{ARGV.join(" ")}")
52
+ end
53
+
54
+ File.delete(file_path) if File.exists?(file_path)
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ module Delayed
4
+ class Job
5
+ def log_exception(exception)
6
+ # do nothing for now
7
+ end
8
+ def name
9
+ "My delayed job"
10
+ end
11
+ end
12
+ end
13
+
14
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'sfalma', 'integration', 'dj')
15
+
16
+ describe Delayed::Job do
17
+ before :each do
18
+ @job = Delayed::Job.new
19
+ @exception = StandardError.new
20
+ end
21
+ it "should handle exceptions with Sfalma" do
22
+ Sfalma.should_receive(:handle).with(@exception, "Delayed::Job My delayed job")
23
+ @job.log_exception(@exception)
24
+ end
25
+ it "should clear context" do
26
+ Sfalma.should_receive(:clear!)
27
+ @job.log_exception(@exception)
28
+ end
29
+ end
Binary file
@@ -0,0 +1,10 @@
1
+ api-key: abc123
2
+ ssl: true
3
+ remote-port: 123
4
+ remote-host: example.com
5
+ http-proxy-host: annoying-proxy.example.com
6
+ http-proxy-port: 1066
7
+ http-proxy-username: bob
8
+ http-proxy-password: jack
9
+ http-open-timeout: 5
10
+ http-read-timeout: 10
@@ -0,0 +1,4 @@
1
+ api-key: abc123
2
+
3
+ production:
4
+ enabled: false
@@ -0,0 +1,33 @@
1
+ require 'ginger'
2
+
3
+ class ScenarioWithName < Ginger::Scenario
4
+ attr_accessor :name
5
+ def initialize(name)
6
+ @name = name
7
+ end
8
+ end
9
+
10
+ def is_ruby_19?
11
+ RUBY_VERSION[0..2].eql?('1.9')
12
+ end
13
+
14
+ def create_scenario(version)
15
+ scenario = ScenarioWithName.new("Rails #{version} on ruby: #{[RUBY_VERSION, RUBY_PATCHLEVEL, RUBY_RELEASE_DATE, RUBY_PLATFORM].join(' ')}")
16
+ scenario[/^active_?support$/] = version
17
+ scenario[/^active_?record$/] = version
18
+ scenario[/^action_?pack$/] = version
19
+ scenario[/^action_?controller$/] = version
20
+ scenario[/^rails$/] = version
21
+ scenario
22
+ end
23
+
24
+ Ginger.configure do |config|
25
+ config.aliases["active_record"] = "activerecord"
26
+ config.aliases["active_support"] = "activesupport"
27
+ config.aliases["action_controller"] = "actionpack"
28
+
29
+ config.scenarios << create_scenario("2.3.3")
30
+ config.scenarios << create_scenario("2.3.4")
31
+ config.scenarios << create_scenario("2.3.5")
32
+ config.scenarios << create_scenario("3.0.3")
33
+ end
@@ -0,0 +1,21 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'rack/mock'
3
+
4
+ class SfalmaTestError < StandardError
5
+ end
6
+
7
+ describe Rack::Sfalma do
8
+
9
+ before(:each) do
10
+ Sfalma::Config.should_receive(:load)
11
+ @error = SfalmaTestError.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::Sfalma.new(@app)
18
+ Sfalma::Catcher.should_receive(:handle_with_rack)
19
+ lambda { rr.call(@env)}.should raise_error(SfalmaTestError)
20
+ end
21
+ end
@@ -0,0 +1,95 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'sfalma', 'integration', 'rails')
3
+
4
+ describe Sfalma, 'version number' do
5
+ it "be available proramatically" do
6
+ Sfalma::VERSION.should =~ /\d+\.\d+\.\d+/
7
+ end
8
+ end
9
+
10
+ describe ActiveSupport::JSON, 'standards compliant json' do
11
+ it "quote keys" do
12
+ {:a => '123'}.to_json.gsub(/ /, '').should == '{"a":"123"}'
13
+ end
14
+ end
15
+
16
+ class TestingController < ActionController::Base
17
+ filter_parameter_logging :password, /credit_card/
18
+
19
+ def raises_something
20
+ raise StandardError
21
+ end
22
+ end
23
+
24
+ describe TestingController do
25
+ before :each do
26
+ @controller = TestingController.new
27
+ end
28
+
29
+ it 'handle exception with Sfalma::Catcher' do
30
+ Sfalma::Catcher.should_receive(:handle_with_controller).with(an_instance_of(StandardError), @controller, an_instance_of(ActionController::TestRequest))
31
+ send_request(:raises_something)
32
+ end
33
+
34
+ it "still return an error response to the user" do
35
+ Sfalma::Catcher.stub!(:handle_with_controller)
36
+ send_request(:raises_something)
37
+ @response.code.should == '500'
38
+ end
39
+
40
+ it "filters paramaters based on controller filter_parameter_logging" do
41
+ Sfalma::Config.stub!(:should_send_to_api?).and_return(true)
42
+ Sfalma::Remote.should_receive(:error) {|exception_data|
43
+ exception_data.to_hash['request']['parameters']['credit_card_number'].should == '[FILTERED]'
44
+ }
45
+ send_request(:raises_something, {:credit_card_number => '1234566777775453', :something_else => 'boo'})
46
+ end
47
+ end
48
+
49
+ if ActionController::Base.respond_to?(:rescue_from)
50
+ class CustomError < StandardError;
51
+ end
52
+ class TestingWithRescueFromController < ActionController::Base
53
+ rescue_from CustomError, :with => :custom_handler
54
+
55
+ def raises_custom_error
56
+ raise CustomError.new
57
+ end
58
+
59
+ def raises_other_error
60
+ raise StandardError.new
61
+ end
62
+
63
+ def raises_with_context
64
+ Sfalma.context('foo' => 'bar')
65
+ raise StandardError.new
66
+ end
67
+
68
+ def custom_handler
69
+ head :ok
70
+ end
71
+ end
72
+
73
+ describe TestingWithRescueFromController do
74
+ before :each do
75
+ @controller = TestingWithRescueFromController.new
76
+ end
77
+
78
+ it 'not handle exception with Sfalma that is dealt with by rescue_from' do
79
+ Sfalma::Catcher.should_not_receive(:handle_with_controller)
80
+ send_request(:raises_custom_error)
81
+ end
82
+ it 'handle exception with Sfalma that is not dealt with by rescue_from' do
83
+ Sfalma::Catcher.should_receive(:handle_with_controller)
84
+ send_request(:raises_other_error)
85
+ end
86
+ it "has context and clears context after request" do
87
+ Sfalma::Config.should_receive(:should_send_to_api?).and_return(true)
88
+ Sfalma::Remote.should_receive(:error) {|exception_data|
89
+ exception_data.to_hash['context']['foo'] == 'bar'
90
+ }
91
+ send_request(:raises_with_context)
92
+ Thread.current[:sfalma_context].should == nil
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'rack/mock'
3
+
4
+ class SfalmaTestError < StandardError
5
+ end
6
+
7
+ describe Rack::RailsExceptional do
8
+
9
+ class TestingController < ActionController::Base
10
+ filter_parameter_logging :password, /credit_card/
11
+
12
+ def raises_something
13
+ raise StandardError
14
+ end
15
+ end
16
+
17
+ before(:each) do
18
+ @error = SfalmaTestError.new
19
+ @app = lambda { |env| raise @error, 'Whoops!' }
20
+ @env = Rack::MockRequest.env_for("/foo")
21
+ @env['action_controller.instance'] = TestingController.new
22
+ end
23
+
24
+ it 're-raises errors caught in the middleware' do
25
+ rr = Rack::RailsSfalma.new(@app)
26
+ Sfalma::Catcher.should_receive(:handle_with_controller)
27
+ lambda { rr.call(@env)}.should raise_error(SfalmaTestError)
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Sfalma::AlertData do
4
+ it "raises error" do
5
+ data = Sfalma::AlertData.new(Sfalma::Alert.new("A string"), "Alert")
6
+ result_json = JSON.parse(data.to_json)
7
+ result_json['rescue_block']['name'].should == 'Alert'
8
+ result_json['sfalma']['message'].should == "A string"
9
+ result_json['sfalma']['exception_class'] == 'Sfalma::Alert'
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Sfalma::Catcher do
4
+ it "should create exception_data object and send json to the api" do
5
+ Sfalma::Config.should_receive(:should_send_to_api?).and_return(true)
6
+ exception = mock('exception')
7
+ controller = mock('controller')
8
+ request = mock('request')
9
+ Sfalma::ControllerExceptionData.should_receive(:new).with(exception,controller,request).and_return(data = mock('exception_data'))
10
+ Sfalma::Remote.should_receive(:error).with(data)
11
+ Sfalma::Catcher.handle_with_controller(exception,controller,request)
12
+ end
13
+ end