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.
- data/bin/sfalma +76 -0
- data/init.rb +27 -0
- data/install.rb +19 -0
- data/lib/sfalma/alert_data.rb +15 -0
- data/lib/sfalma/application_environment.rb +79 -0
- data/lib/sfalma/catcher.rb +26 -0
- data/lib/sfalma/config.rb +93 -0
- data/lib/sfalma/controller_exception_data.rb +69 -0
- data/lib/sfalma/exception_data.rb +146 -0
- data/lib/sfalma/integration/alerter.rb +11 -0
- data/lib/sfalma/integration/dj.rb +12 -0
- data/lib/sfalma/integration/rack.rb +28 -0
- data/lib/sfalma/integration/rack_rails.rb +26 -0
- data/lib/sfalma/integration/rails.rb +27 -0
- data/lib/sfalma/integration/sinatra.rb +6 -0
- data/lib/sfalma/integration/tester.rb +20 -0
- data/lib/sfalma/log_factory.rb +39 -0
- data/lib/sfalma/monkeypatches.rb +10 -0
- data/lib/sfalma/rack_exception_data.rb +29 -0
- data/lib/sfalma/railtie.rb +20 -0
- data/lib/sfalma/remote.rb +59 -0
- data/lib/sfalma/startup.rb +14 -0
- data/lib/sfalma/vcs.rb +45 -0
- data/lib/sfalma/version.rb +3 -0
- data/lib/sfalma.rb +71 -0
- data/lib/tasks/sfalma_tasks.rake +11 -0
- data/rails/init.rb +1 -0
- data/sfalma.gemspec +18 -0
- data/spec/bin/ginger +54 -0
- data/spec/dj_integration_spec.rb +29 -0
- data/spec/fixtures/favicon.png +0 -0
- data/spec/fixtures/sfalma.yml +10 -0
- data/spec/fixtures/sfalma_disabled.yml +4 -0
- data/spec/ginger_scenarios.rb +33 -0
- data/spec/rack_integration_spec.rb +21 -0
- data/spec/rails_integration_spec.rb +95 -0
- data/spec/rails_rack_integration_spec.rb +29 -0
- data/spec/sfalma/alert_exception_data_spec.rb +11 -0
- data/spec/sfalma/catcher_spec.rb +13 -0
- data/spec/sfalma/config_spec.rb +64 -0
- data/spec/sfalma/controller_exception_data_spec.rb +26 -0
- data/spec/sfalma/exception_data_spec.rb +198 -0
- data/spec/sfalma/monkeypatches_spec.rb +11 -0
- data/spec/sfalma/rack_exception_data_spec.rb +87 -0
- data/spec/sfalma/remote_spec.rb +31 -0
- data/spec/sfalma/startup_spec.rb +15 -0
- data/spec/sfalma_rescue_spec.rb +74 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/standalone_spec.rb +9 -0
- 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,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
|
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,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
|