ixtlan-error-handler 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Kristian Meier
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,31 @@
1
+ h1. Rails Error Dumper
2
+
3
+ p. the main idea here is notify the developers on error but in a way to protect privacy of the users of the system. to do so ALL data need to remain on the server and they need to be deleted after period of time.
4
+
5
+ * first to dump as much as possible onto the filesystem of the server when an error occurs, i.e. the environment, the request, the response, the session, etc
6
+
7
+ * notify the developers
8
+
9
+ * delete expired error dumps
10
+
11
+ p. the next idea is to collect all possible rails exception and map them to three error pages and pass on a message. for each exception you can decide whether an error dump is needed or not.
12
+
13
+ h2. install
14
+
15
+ p. in Gemfile add *gem 'ixtlan-error-handler'*
16
+
17
+ p. for the configuration add for example in _config/initializers/error_handler.rb_
18
+
19
+ bc. config.error_dumper.dump_dir = Rails.root + "/log/errors" # default: log/errors
20
+ config.error_dumper.email_from = "no-reply@example.com"
21
+ config.error_dumper.email_to = "developer1@example.com,developer2@example.com"
22
+ config.error_dumper.keep_dumps = 30 # days
23
+ config.skip_rescue_module = true # do not include the predefined Rescue
24
+
25
+ h2. relation to ixtlan gem
26
+
27
+ p. the ixtlan gem provides a setup generator which adds configuration examples for this gem in _config/initializer/ixtlan.rb_ (the dynamic configuration is part of the ixtlan gem and it is just easier to keep that inside that gem !!!)
28
+
29
+ h2. relation to ixtlan-audit gem
30
+
31
+ p. if that gem is present and loaded than any error will be log with the help of _Ixtlan::Audit::UserLogger_
@@ -1,85 +1,110 @@
1
1
  require 'ixtlan/errors/mailer'
2
2
  require 'fileutils'
3
+ require 'slf4r/logger'
4
+
5
+ # unless Fixnum.respond_to? :days
6
+ # class Fixnum
7
+ # def days
8
+ # self
9
+ # end
10
+
11
+ # def ago
12
+ # DateTime.now - 86000 * self
13
+ # end
14
+ # end
15
+ # end
3
16
 
4
17
  module Ixtlan
5
18
  module Errors
6
19
  class ErrorDumper
7
20
 
8
- attr_accessor :dump_dir, :email_from, :email_to, :keep_dumps
21
+ private
22
+
23
+ include ::Slf4r::Logger
24
+
25
+ public
26
+
27
+ attr_accessor :from_email, :to_emails, :keep_dumps, :base_url
9
28
 
10
- def keep_dumps
11
- @keep_dumps ||= 90
29
+ def initialize
30
+ @keep_dumps = 30
12
31
  end
13
32
 
14
33
  def keep_dumps=(ttl)
34
+ old = @keep_dumps
15
35
  @keep_dumps = ttl.to_i
16
- cleanup
36
+ daily_cleanup if old != @keep_dumps
17
37
  end
18
-
19
- def dump_dir
20
- if @dump_dir.blank?
21
- @dump_dir = File.join(Rails.root, "log", "errors")
22
- FileUtils.mkdir_p(@dump_dir)
23
- end
24
- @dump_dir
38
+
39
+ def error_dump_model(model = nil)
40
+ @error_dump ||= model.nil? ? ::Error : model.classify
25
41
  end
26
42
 
27
- def dump_dir=(dir)
28
- @dump_dir = dir
29
- FileUtils.mkdir_p(@dump_dir) unless dir.blank?
30
- @dump_dir
31
- end
32
-
33
43
  def dump(controller, exception)
34
- cleanup
35
- log_file = log_filename
36
- logger = Logger.new(log_file)
44
+ daily_cleanup
37
45
 
38
- dump_environment(logger, exception, controller)
39
- Mailer.error_notification(@email_from, @email_to, exception, log_file).deliver unless (@email_to.blank? || @email_from.blank?)
40
- log_file
46
+ error = dump_environment(exception, controller)
47
+ Mailer.error_notification(@from_email, @to_emails, exception, "#{@base_url}/#{error.id}").deliver unless (@to_emails.blank? || @from_email.blank?)
48
+ "#{@base_url}/#{error.id}"
41
49
  end
42
50
 
43
51
  private
44
52
 
45
- def log_filename(time = Time.now)
46
- error_log_id = "#{time.tv_sec}#{time.tv_usec}"
47
- File.join(dump_dir, "error-#{error_log_id}.log")
48
- end
53
+ def dump_environment(exception, controller)
54
+ dump = error_dump_model.new
55
+
56
+ dump.request = dump_hashmap(controller.request.env)
49
57
 
50
- def dump_environment_header(logger, header)
51
- logger.error("\n===================================================================\n#{header}\n===================================================================\n");
52
- end
58
+ dump.response = dump_hashmap(controller.response.headers)
53
59
 
54
- def dump_environment(logger, exception, controller)
55
- dump_environment_header(logger, "REQUEST DUMP");
56
- dump_hashmap(logger, controller.request.env)
60
+ dump.session = dump_hashmap(controller.session)
57
61
 
58
- dump_environment_header(logger, "RESPONSE DUMP");
59
- dump_hashmap(logger, controller.response.headers)
62
+ dump.parameters = dump_hashmap(controller.params)
60
63
 
61
- dump_environment_header(logger, "SESSION DUMP");
62
- dump_hashmap(logger, controller.session)
64
+ dump.message = exception.message
65
+
66
+ dump.clazz = exception.class.to_s
67
+
68
+ dump.backtrace = exception.backtrace.join("\n") if exception.backtrace
63
69
 
64
- dump_environment_header(logger, "PARAMETER DUMP");
65
- map = {}
66
- dump_hashmap(logger, controller.params.each{ |k,v| map[k]=v })
70
+ dump if dump.save
71
+ end
67
72
 
68
- dump_environment_header(logger, "EXCEPTION");
69
- logger.error("#{exception.class}:#{exception.message}")
70
- logger.error("\t" + exception.backtrace.join("\n\t")) if exception.backtrace
73
+ def dump_hashmap(map, indent = '')
74
+ result = ''
75
+ map.each do |key,value|
76
+ if value.is_a? Hash
77
+ result << "#{indent}#{key} => {\n"
78
+ result << dump_hashmap(value, "#{indent} ")
79
+ result << "#{indent}}\n"
80
+ else
81
+ result << "#{indent}#{key} => #{value.nil? ? 'nil': value}\n"
82
+ end
83
+ end
84
+ result
71
85
  end
72
86
 
73
- def dump_hashmap(logger, map)
74
- for key,value in map
75
- logger.error("\t#{key} => #{value.inspect}")
87
+ def daily_cleanup
88
+ if(@last_cleanup.nil? || @last_cleanup < 1.days.ago)
89
+ @last_cleanup = 0.days.ago # to have the right type
90
+ begin
91
+ delete_all
92
+ logger.info("cleaned error dumps")
93
+ rescue Exception => e
94
+ logger.error("cleanup error dumps", e)
95
+ end
76
96
  end
77
97
  end
78
98
 
79
- def cleanup
80
- ref_log_file = log_filename(keep_dumps.ago)
81
- Dir[File.join(dump_dir, "error-*.log")].each do |f|
82
- FileUtils.rm(f) if File.basename(f) < ref_log_file
99
+ private
100
+
101
+ if defined? ::DataMapper
102
+ def delete_all
103
+ error_dump_model.all(:created_at.lte => keep_dumps.days.ago).destroy!
104
+ end
105
+ else # ActiveRecord
106
+ def delete_all
107
+ error_dump_model.all(:conditions => ["created_at <= ?", keep_dumps.days.ago]).each(&:delete)
83
108
  end
84
109
  end
85
110
  end
@@ -0,0 +1,79 @@
1
+ module Ixtlan
2
+ module Errors
3
+ class ErrorDumper
4
+
5
+ def initialize
6
+ configure
7
+ end
8
+
9
+ def configure(error_dir = nil, email_from = nil, emails_to = nil, time_to_live = 90)
10
+ if config
11
+ @email_from = email_from
12
+ @email_to = emails_to
13
+ @errors_dir = errors_dir
14
+ else
15
+ @email_from = nil
16
+ @email_to = nil
17
+ end
18
+
19
+ @time_to_live = time_to_live
20
+ @errors_dir ||= File.join(Rails.root, "log", "errors")
21
+ FileUtils.mkdir_p(@errors_dir)
22
+ cleanup
23
+ end
24
+
25
+ def dump(controller, exception)
26
+ cleanup
27
+ log_file = log_filename
28
+ logger = Logger.new(log_file)
29
+
30
+ dump_environment(logger, exception, controller)
31
+ Mailer.deliver_error_notification(@email_from, @email_to, exception, log_file) unless (@email_to.blank? || @email_from.blank?)
32
+ log_file
33
+ end
34
+
35
+ private
36
+
37
+ def log_filename(time = Time.now)
38
+ error_log_id = "#{time.tv_sec}#{time.tv_usec}"
39
+ File.join(@errors_dir, "error-#{error_log_id}.log")
40
+ end
41
+
42
+ def dump_environment_header(logger, header)
43
+ logger.error("\n===================================================================\n#{header}\n===================================================================\n");
44
+ end
45
+
46
+ def dump_environment(logger, exception, controller)
47
+ dump_environment_header(logger, "REQUEST DUMP");
48
+ dump_hashmap(logger, controller.request.env)
49
+
50
+ dump_environment_header(logger, "RESPONSE DUMP");
51
+ dump_hashmap(logger, controller.response.headers)
52
+
53
+ dump_environment_header(logger, "SESSION DUMP");
54
+ dump_hashmap(logger, controller.session)
55
+
56
+ dump_environment_header(logger, "PARAMETER DUMP");
57
+ map = {}
58
+ dump_hashmap(logger, controller.params.each{ |k,v| map[k]=v })
59
+
60
+ dump_environment_header(logger, "EXCEPTION");
61
+ logger.error("#{exception.class}:#{exception.message}")
62
+ logger.error("\t" + exception.backtrace.join("\n\t"))
63
+ end
64
+
65
+ def dump_hashmap(logger, map)
66
+ for key,value in map
67
+ logger.error("\t#{key} => #{value.inspect}")
68
+ end
69
+ end
70
+
71
+ def cleanup
72
+ ref_log_file = log_filename(@time_to_live.ago)
73
+ Dir[File.join(@error_dir, "error-*.log")].each do |f|
74
+ FileUtils.rm(f) if File.basename(f) < ref_log_file
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -14,23 +14,12 @@ module Ixtlan
14
14
  log_user_error(exception)
15
15
  error_page(:not_found, "page not found")
16
16
  end
17
- #status = rescue_responses[exception.class.name]
18
- #status = status == :internal_server_error ? :not_found : status
19
- #error_page(status, "page not found")
20
17
 
21
18
  def stale_resource(exception)
22
19
  log_user_error(exception)
23
20
  error_page(:conflict, "stale resource")
24
21
  end
25
22
 
26
- # respond_to do |format|
27
- # format.html {
28
- # render_stale_error_page
29
- # }
30
- # format.xml { head :conflict }
31
- # end
32
- # end
33
-
34
23
  def render_error_page_with_session(status)
35
24
  render :template => "errors/error_with_session", :status => status
36
25
  end
@@ -39,10 +28,6 @@ module Ixtlan
39
28
  render :template => "errors/error", :status => status
40
29
  end
41
30
 
42
- # def render_stale_error_page
43
- # render :template => "errors/stale", :status => :conflict
44
- # end
45
-
46
31
  private
47
32
 
48
33
  if defined? ::Ixtlan::Audit
@@ -0,0 +1,79 @@
1
+ module Ixtlan
2
+ module Errors
3
+ module ErrorHandling
4
+
5
+ protected
6
+
7
+ def internal_server_error(exception)
8
+ dump_error(exception)
9
+ status = :internal_server_error
10
+ error_page(:internal_server_error, exception, "internal server error: #{exception.class.name}")
11
+ end
12
+ end
13
+
14
+ def page_not_found(exception)
15
+ log_user_error(exception)
16
+ status = rescue_responses[exception.class.name]
17
+ status = status == :internal_server_error ? :not_found : status
18
+ error_page(status, exception, "page not found")
19
+ end
20
+
21
+ def stale_resource(exception)
22
+ log_user_error(exception)
23
+ respond_to do |format|
24
+ format.html {
25
+ render_stale_error_page
26
+ }
27
+ format.xml { head :conflict }
28
+ end
29
+ end
30
+
31
+ def render_error_page_with_session(status)
32
+ render :template => "errors/error_with_session", :status => status
33
+ end
34
+
35
+ def render_error_page(status)
36
+ render :template => "errors/error", :status => status
37
+ end
38
+
39
+ def render_stale_error_page
40
+ render :template => "errors/stale", :status => :conflict
41
+ end
42
+
43
+ private
44
+
45
+ if defined? ::Ixtlan::Audit
46
+ def user_logger
47
+ @user_logger ||= Ixtlan::Audit::UserLogger.new(ErrorHandling)
48
+ end
49
+
50
+ def log_user_error(exception)
51
+ user_logger.log_action(self, " - #{exception.class} - #{exception.message}")
52
+ log_error(exception)
53
+ end
54
+ else
55
+ alias :log_user_error :log_error
56
+ end
57
+
58
+ def error_page(status, exception, notice)
59
+ respond_to do |format|
60
+ format.html {
61
+ @notice = notice
62
+ if logged_in?
63
+ render_error_page_with_session(status)
64
+ else
65
+ render_error_page(status)
66
+ end
67
+ }
68
+ # TODO add the notice there as well. how ?
69
+ format.xml { head status }
70
+ end
71
+ end
72
+
73
+ def dump_error(exception)
74
+ log_user_error(exception)
75
+ Rails.configuration.error_dumper.dump(self, exception)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,79 @@
1
+ module Ixtlan
2
+ module Errors
3
+ module ErrorHandling
4
+
5
+ protected
6
+
7
+ def internal_server_error(exception)
8
+ dump_error(exception)
9
+ status = :internal_server_error
10
+ error_page(:internal_server_error, exception) do |exception|
11
+ "internal server error: #{exception.class.name}"
12
+ end
13
+ end
14
+
15
+ def page_not_found(exception)
16
+ log_user_error(exception)
17
+ status = rescue_responses[exception.class.name]
18
+ status = status == :internal_server_error ? :not_found : status
19
+ error_page(status, exception) { "page not found" }
20
+ end
21
+
22
+ def stale_resource(exception)
23
+ log_user_error(exception)
24
+ respond_to do |format|
25
+ format.html {
26
+ render_stale_error_page
27
+ }
28
+ format.xml { head :conflict }
29
+ end
30
+ end
31
+
32
+ def render_error_page_with_session(status)
33
+ render :template => "errors/error_with_session", :status => status
34
+ end
35
+
36
+ def render_error_page(status)
37
+ render :template => "errors/error", :status => status
38
+ end
39
+
40
+ def render_stale_error_page
41
+ render :template => "errors/stale", :status => :conflict
42
+ end
43
+
44
+ private
45
+
46
+ if defined? ::Ixtlan::Audit
47
+ def user_logger
48
+ @user_logger ||= Ixtlan::UserLogger.new(Ixtlan::Core::ErrorHandling)
49
+ end
50
+ def log_user_error(exception)
51
+ user_logger.log_action(self, " - #{exception.class} - #{exception.message}")
52
+ log_error(exception)
53
+ end
54
+ else
55
+ alias :log_user_error :log_error
56
+ end
57
+
58
+ def error_page(status, exception, &block)
59
+ respond_to do |format|
60
+ format.html {
61
+ @notice = block.call(exception)
62
+ if logged_in?
63
+ render_error_page_with_session(status)
64
+ else
65
+ render_error_page(status)
66
+ end
67
+ }
68
+ format.xml { head status }
69
+ end
70
+ end
71
+
72
+ def dump_error(exception)
73
+ log_user_error(exception)
74
+ dumper = Rails.configuration.error_dumper
75
+ dumper.dump(self, exception)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -2,9 +2,9 @@ module Ixtlan
2
2
  module Errors
3
3
  class Mailer < ActionMailer::Base
4
4
 
5
- def error_notification(email_from, emails_to, exception, error_file)
5
+ def error_notification(email_from, emails_to, exception, error_url)
6
6
  @subject = exception.message
7
- @text = "#{error_file}"
7
+ @text = "#{error_url}"
8
8
  @recipients = emails_to
9
9
  @from = email_from
10
10
  @sent_on = Time.now
@@ -0,0 +1,19 @@
1
+ module Ixtlan
2
+ module Errors
3
+ class Mailer < ActionMailer::Base
4
+
5
+ path = File.join(File.dirname(__FILE__), "mailer")
6
+ view_paths << path unless view_paths.member? path
7
+
8
+
9
+ def error_notification(email_from, emails_to, exception, error_file)
10
+ @subject = exception.message
11
+ @body = {:text => "#{error_file}"}
12
+ @recipients = emails_to
13
+ @from = email_from
14
+ @sent_on = Time.now
15
+ @headers = {}
16
+ end
17
+ end
18
+ end
19
+ end
@@ -14,11 +14,8 @@ module Ixtlan
14
14
  ActionMailer::Base.view_paths= [ActionMailer::Base.view_paths, path].flatten
15
15
  end
16
16
 
17
- app.config.class.class_eval do
18
- attr_accessor :error_dumper, :skip_rescue_module
19
- app.config.error_dumper = ErrorDumper.new
20
- app.config.skip_rescue_module = false
21
- end
17
+ app.config.error_dumper = ErrorDumper.new
18
+ app.config.skip_rescue_module = false
22
19
  end
23
20
 
24
21
  config.after_initialize do |app|
@@ -0,0 +1,20 @@
1
+ require 'rails'
2
+
3
+ module Ixtlan
4
+ module Errors
5
+ class Railtie < Rails::Railtie
6
+
7
+ config.before_configuration do |app|
8
+ app.config.class.class_eval do
9
+ attr_accessor :error_dumper
10
+ app.config.error_dumper = Ixtlan::Errors::ErrorDumper.new
11
+ end
12
+ end
13
+
14
+ config.after_initialization do |app|
15
+ ::ActionController::Base.send(:include, Ixtlan::Errors::RescueModule)
16
+ ::ActionController::Base.send(:include, Ixtlan::Errors::ErrorHandler)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,41 @@
1
+ module Ixtlan
2
+ module Errors
3
+ module RescueModule
4
+ def self.included(controller)
5
+ if defined? ::Ixtlan::ModifiedBy
6
+ # needs 'optimistic_persistence'
7
+ controller.rescue_from ::Ixtlan::ModifiedBy::StaleResourceError, :with => :stale_resource
8
+ end
9
+
10
+ if defined? ::Ixtlan::Guard
11
+ # needs 'guard'
12
+ controller.rescue_from ::Ixtlan::Guard::GuardException, :with => :page_not_found
13
+ controller.rescue_from ::Ixtlan::Guard::PermissionDenied, :with => :page_not_found
14
+ end
15
+
16
+ if defined? ::DataMapper
17
+ # datamapper
18
+ controller.rescue_from ::DataMapper::ObjectNotFoundError, :with => :page_not_found
19
+ end
20
+
21
+ if defined? ::ActiveRecord
22
+ # activerecord
23
+ controller.rescue_from ::ActiveRecord::RecordNotFound, :with => :page_not_found
24
+ end
25
+
26
+ # standard rails controller
27
+ controller.rescue_from ::ActionController::RoutingError, :with => :page_not_found
28
+ controller.rescue_from ::ActionController::UnknownAction, :with => :page_not_found
29
+ controller.rescue_from ::ActionController::MethodNotAllowed, :with => :page_not_found
30
+ controller.rescue_from ::ActionController::NotImplemented, :with => :page_not_found
31
+ controller.rescue_from ::ActionController::InvalidAuthenticityToken, :with => :stale_resource
32
+
33
+ # have nice stacktraces in development mode
34
+ unless controller.consider_all_requests_local
35
+ controller.rescue_from ::ActionView::MissingTemplate, :with => :internal_server_error
36
+ controller.rescue_from ::ActionView::TemplateError, :with => :internal_server_error
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,3 +1,27 @@
1
+ require 'dm-core'
2
+ require 'dm-migrations'
3
+ require 'slf4r/ruby_logger'
4
+
5
+ class Error
6
+ include DataMapper::Resource
7
+
8
+ property :id, Serial
9
+
10
+ property :message, String
11
+ property :clazz, String
12
+ property :request, Text
13
+ property :response, Text
14
+ property :session, Text
15
+ property :parameters, Text
16
+ property :backtrace, Text
17
+
18
+ property :created_at, DateTime
19
+
20
+ before :save do
21
+ self.created_at = DateTime.now
22
+ end
23
+ end
24
+
1
25
  module Ixtlan
2
26
  module Errors
3
27
  module ActionMailer
@@ -62,8 +86,11 @@ class String
62
86
  end
63
87
 
64
88
  class Fixnum
89
+ def days
90
+ self
91
+ end
65
92
  def ago
66
- DateTime.now - self.to_i
93
+ DateTime.now - 86000 * self
67
94
  end
68
95
  end
69
96
 
@@ -76,37 +103,44 @@ class DateTime
76
103
  end
77
104
  end
78
105
 
106
+ DataMapper.setup(:default, "sqlite3::memory:")
107
+ DataMapper.finalize
108
+ DataMapper.repository.auto_migrate!
109
+
79
110
  describe Ixtlan::Errors::ErrorDumper do
80
111
 
81
112
  before :each do
82
113
  @dumper = Ixtlan::Errors::ErrorDumper.new
83
- @dumper.dump_dir = "target"
114
+ @dumper.base_url = "http://localhost"
84
115
  @controller = Controller.new
85
116
  end
86
117
 
87
118
  it "should dump env and not send notification" do
88
- file = @dumper.dump(@controller, StandardError.new("dump it"))
89
- File.exists?(file).should be_true
90
- @dumper.email_from = "asd"
91
- file = @dumper.dump(@controller, StandardError.new("dump it"))
92
- File.exists?(file).should be_true
93
- @dumper.email_from = nil
94
- @dumper.email_to = "dsa"
95
- file = @dumper.dump(@controller, StandardError.new("dump it"))
96
- File.exists?(file).should be_true
119
+ url = @dumper.dump(@controller, StandardError.new("dump it"))
120
+ url.should =~ /http:\/\/localhost\/[0-9]+/
121
+ @dumper.from_email = "asd"
122
+ url = @dumper.dump(@controller, StandardError.new("dump it"))
123
+ url.should =~ /http:\/\/localhost\/[0-9]+/
124
+ @dumper.from_email = nil
125
+ @dumper.to_emails = "dsa"
126
+ url = @dumper.dump(@controller, StandardError.new("dump it"))
127
+ url.should =~ /http:\/\/localhost\/[0-9]+/
97
128
  end
98
129
 
99
130
  it "should clean up error dumps" do
131
+ Error.create(:message => 'msg')
132
+ Error.all.size.should > 0
100
133
  @dumper.keep_dumps = 0
134
+ Error.all.size.should == 0
101
135
  @dumper.dump(@controller, StandardError.new("dump it"))
102
- Dir['target/error-*'].size.should == 1
136
+ Error.all.size.should == 1
103
137
  @dumper.dump(@controller, StandardError.new("dump it"))
104
- Dir['target/error-*'].size.should == 1
138
+ Error.all.size.should == 2
105
139
  end
106
140
 
107
141
  it "should send notifications" do
108
- @dumper.email_to = "das"
109
- @dumper.email_from = "asd"
142
+ @dumper.to_emails = "das"
143
+ @dumper.from_email = "asd"
110
144
  @dumper.dump(@controller, StandardError.new("dump it"))
111
145
  Ixtlan::Errors::ActionMailer::Base.delivered.should be_true
112
146
  end
@@ -0,0 +1,8 @@
1
+ require 'ixtlan/errors/error_dumper'
2
+
3
+
4
+ describe Ixtlan::Errors::ErrorDumper do
5
+
6
+
7
+
8
+ end
@@ -0,0 +1,60 @@
1
+ require 'ixtlan/errors/error_dumper'
2
+ require 'date'
3
+ require 'logger'
4
+
5
+ class Controller
6
+
7
+ def request
8
+ self
9
+ end
10
+ def env
11
+ @env ||= {:one => 1, :two => 2, :three => 3}
12
+ end
13
+
14
+ def response
15
+ self
16
+ end
17
+
18
+ def headers
19
+ @headers ||= { 'ONE' => 1, "TWO" => 2 }
20
+ end
21
+
22
+ def session
23
+ @session ||= { "user" => "me" }
24
+ end
25
+
26
+ def params
27
+ @params ||= { :query => "all" }
28
+ end
29
+ end
30
+
31
+ class NilClass
32
+ def blank?
33
+ true
34
+ end
35
+ end
36
+
37
+ class String
38
+ def blank?
39
+ size == 0
40
+ end
41
+ end
42
+
43
+ class Fixnum
44
+ def ago
45
+ DateTime.now - self.to_i
46
+ end
47
+ end
48
+
49
+ # class DateTime
50
+ # def tv_sec
51
+ # sec
52
+ # end
53
+ # def tv_usec
54
+ # 0
55
+ # end
56
+ # end
57
+
58
+ describe Ixtlan::Errors::ErrorHandler do
59
+
60
+ end
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ixtlan-error-handler
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 1
9
- version: 0.1.1
4
+ prerelease:
5
+ version: 0.2.0
10
6
  platform: ruby
11
7
  authors:
12
8
  - mkristian
@@ -14,51 +10,75 @@ autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
12
 
17
- date: 2011-03-22 00:00:00 +05:30
13
+ date: 2011-11-04 00:00:00 +05:30
18
14
  default_executable:
19
15
  dependencies:
20
16
  - !ruby/object:Gem::Dependency
21
- name: rspec
17
+ name: slf4r
22
18
  prerelease: false
23
19
  requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
24
21
  requirements:
25
- - - "="
22
+ - - ~>
26
23
  - !ruby/object:Gem::Version
27
- segments:
28
- - 2
29
- - 4
30
- - 0
31
- version: 2.4.0
32
- type: :development
24
+ version: 0.4.2
25
+ type: :runtime
33
26
  version_requirements: *id001
34
27
  - !ruby/object:Gem::Dependency
35
- name: rake
28
+ name: rspec
36
29
  prerelease: false
37
30
  requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
38
32
  requirements:
39
33
  - - "="
40
34
  - !ruby/object:Gem::Version
41
- segments:
42
- - 0
43
- - 8
44
- - 7
45
- version: 0.8.7
35
+ version: 2.6.0
46
36
  type: :development
47
37
  version_requirements: *id002
48
38
  - !ruby/object:Gem::Dependency
49
- name: cucumber
39
+ name: rake
50
40
  prerelease: false
51
41
  requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
52
43
  requirements:
53
- - - ">="
44
+ - - "="
54
45
  - !ruby/object:Gem::Version
55
- segments:
56
- - 0
57
- - 0
58
- - 0
59
- version: 0.0.0
46
+ version: 0.8.7
60
47
  type: :development
61
48
  version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: dm-core
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - "="
56
+ - !ruby/object:Gem::Version
57
+ version: 1.2.0
58
+ type: :development
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: dm-migrations
62
+ prerelease: false
63
+ requirement: &id005 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - "="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.2.0
69
+ type: :development
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: dm-sqlite-adapter
73
+ prerelease: false
74
+ requirement: &id006 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - "="
78
+ - !ruby/object:Gem::Version
79
+ version: 1.2.0
80
+ type: :development
81
+ version_requirements: *id006
62
82
  description: dump errors on filesystem and notify developers, map different errors to specific pages
63
83
  email:
64
84
  - m.kristian@web.de
@@ -69,15 +89,25 @@ extensions: []
69
89
  extra_rdoc_files: []
70
90
 
71
91
  files:
92
+ - MIT-LICENSE
93
+ - README.textile
72
94
  - lib/ixtlan-error-handler.rb
73
- - lib/ixtlan/errors/railtie.rb
74
- - lib/ixtlan/errors/error_handler.rb
95
+ - lib/ixtlan/errors/error_dumper.rb
75
96
  - lib/ixtlan/errors/mailer.rb
97
+ - lib/ixtlan/errors/error_handling.rb~
98
+ - lib/ixtlan/errors/rescue_module.rb~
76
99
  - lib/ixtlan/errors/rescue_module.rb
77
- - lib/ixtlan/errors/error_dumper.rb
100
+ - lib/ixtlan/errors/error_dumper.rb~
101
+ - lib/ixtlan/errors/error_handler.rb~
102
+ - lib/ixtlan/errors/railtie.rb~
103
+ - lib/ixtlan/errors/error_handler.rb
104
+ - lib/ixtlan/errors/railtie.rb
105
+ - lib/ixtlan/errors/mailer.rb~
78
106
  - lib/ixtlan/errors/mailer/error_notification.erb
79
- - spec/error_dumper_spec.rb
80
107
  - spec/error_handler_spec.rb
108
+ - spec/error_dumper_spec.rb~
109
+ - spec/error_handler_spec.rb~
110
+ - spec/error_dumper_spec.rb
81
111
  has_rdoc: true
82
112
  homepage: http://github.com/mkristian/ixtlan-error-handler
83
113
  licenses:
@@ -89,26 +119,24 @@ rdoc_options:
89
119
  require_paths:
90
120
  - lib
91
121
  required_ruby_version: !ruby/object:Gem::Requirement
122
+ none: false
92
123
  requirements:
93
124
  - - ">="
94
125
  - !ruby/object:Gem::Version
95
- segments:
96
- - 0
97
126
  version: "0"
98
127
  required_rubygems_version: !ruby/object:Gem::Requirement
128
+ none: false
99
129
  requirements:
100
130
  - - ">="
101
131
  - !ruby/object:Gem::Version
102
- segments:
103
- - 0
104
132
  version: "0"
105
133
  requirements: []
106
134
 
107
135
  rubyforge_project:
108
- rubygems_version: 1.3.6
136
+ rubygems_version: 1.5.1
109
137
  signing_key:
110
138
  specification_version: 3
111
139
  summary: dump errors on filesystem and notify developers
112
140
  test_files:
113
- - spec/error_dumper_spec.rb
114
141
  - spec/error_handler_spec.rb
142
+ - spec/error_dumper_spec.rb