ixtlan-error-handler 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,6 @@
1
1
  require 'ixtlan/errors/mailer'
2
+ require 'fileutils'
3
+
2
4
  module Ixtlan
3
5
  module Errors
4
6
  class ErrorDumper
@@ -15,16 +17,16 @@ module Ixtlan
15
17
  end
16
18
 
17
19
  def dump_dir
18
- unless @dump_dir
20
+ if @dump_dir.blank?
19
21
  @dump_dir = File.join(Rails.root, "log", "errors")
20
22
  FileUtils.mkdir_p(@dump_dir)
21
23
  end
22
24
  @dump_dir
23
25
  end
24
26
 
25
- def dump_dir=(dr)
27
+ def dump_dir=(dir)
26
28
  @dump_dir = dir
27
- FileUtils.mkdir_p(@dump_dir) if dir
29
+ FileUtils.mkdir_p(@dump_dir) unless dir.blank?
28
30
  @dump_dir
29
31
  end
30
32
 
@@ -34,7 +36,7 @@ module Ixtlan
34
36
  logger = Logger.new(log_file)
35
37
 
36
38
  dump_environment(logger, exception, controller)
37
- Mailer.deliver_error_notification(@email_from, @email_to, exception, log_file) unless (@email_to.blank? || @email_from.blank?)
39
+ Mailer.error_notification(@email_from, @email_to, exception, log_file).deliver unless (@email_to.blank? || @email_from.blank?)
38
40
  log_file
39
41
  end
40
42
 
@@ -65,7 +67,7 @@ module Ixtlan
65
67
 
66
68
  dump_environment_header(logger, "EXCEPTION");
67
69
  logger.error("#{exception.class}:#{exception.message}")
68
- logger.error("\t" + exception.backtrace.join("\n\t"))
70
+ logger.error("\t" + exception.backtrace.join("\n\t")) if exception.backtrace
69
71
  end
70
72
 
71
73
  def dump_hashmap(logger, map)
@@ -5,28 +5,32 @@ module Ixtlan
5
5
  protected
6
6
 
7
7
  def internal_server_error(exception)
8
+ log_user_error(exception)
8
9
  dump_error(exception)
9
- status = :internal_server_error
10
- error_page(:internal_server_error, exception, "internal server error: #{exception.class.name}")
10
+ error_page(:internal_server_error, "internal server error: #{exception.class.name}")
11
11
  end
12
12
 
13
13
  def page_not_found(exception)
14
14
  log_user_error(exception)
15
- status = rescue_responses[exception.class.name]
16
- status = status == :internal_server_error ? :not_found : status
17
- error_page(status, exception, "page not found")
15
+ error_page(:not_found, "page not found")
18
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")
19
20
 
20
21
  def stale_resource(exception)
21
22
  log_user_error(exception)
22
- respond_to do |format|
23
- format.html {
24
- render_stale_error_page
25
- }
26
- format.xml { head :conflict }
27
- end
23
+ error_page(:conflict, "stale resource")
28
24
  end
29
25
 
26
+ # respond_to do |format|
27
+ # format.html {
28
+ # render_stale_error_page
29
+ # }
30
+ # format.xml { head :conflict }
31
+ # end
32
+ # end
33
+
30
34
  def render_error_page_with_session(status)
31
35
  render :template => "errors/error_with_session", :status => status
32
36
  end
@@ -35,15 +39,15 @@ module Ixtlan
35
39
  render :template => "errors/error", :status => status
36
40
  end
37
41
 
38
- def render_stale_error_page
39
- render :template => "errors/stale", :status => :conflict
40
- end
42
+ # def render_stale_error_page
43
+ # render :template => "errors/stale", :status => :conflict
44
+ # end
41
45
 
42
46
  private
43
47
 
44
48
  if defined? ::Ixtlan::Audit
45
49
  def user_logger
46
- @user_logger ||= Ixtlan::Audit::UserLogger.new(Rails.application.config.audit_manager)
50
+ @user_logger ||= Ixtlan::Audit::UserLogger.new(Rails.configuration.audit_manager)
47
51
  end
48
52
 
49
53
  def log_user_error(exception)
@@ -56,7 +60,7 @@ module Ixtlan
56
60
  end
57
61
  end
58
62
 
59
- def error_page(status, exception, notice)
63
+ def error_page(status, notice)
60
64
  respond_to do |format|
61
65
  format.html {
62
66
  @notice = notice
@@ -72,7 +76,6 @@ module Ixtlan
72
76
  end
73
77
 
74
78
  def dump_error(exception)
75
- log_user_error(exception)
76
79
  Rails.configuration.error_dumper.dump(self, exception)
77
80
  end
78
81
  end
@@ -4,7 +4,7 @@ module Ixtlan
4
4
 
5
5
  def error_notification(email_from, emails_to, exception, error_file)
6
6
  @subject = exception.message
7
- @body = {:text => "#{error_file}"}
7
+ @text = "#{error_file}"
8
8
  @recipients = emails_to
9
9
  @from = email_from
10
10
  @sent_on = Time.now
@@ -9,7 +9,7 @@ module Ixtlan
9
9
 
10
10
  config.before_configuration do |app|
11
11
 
12
- path = File.join(File.dirname(__FILE__), "mailer")
12
+ path = File.join(File.dirname(__FILE__), "..", "..")
13
13
  unless ActionMailer::Base.view_paths.member? path
14
14
  ActionMailer::Base.view_paths= [ActionMailer::Base.view_paths, path].flatten
15
15
  end
@@ -0,0 +1,113 @@
1
+ module Ixtlan
2
+ module Errors
3
+ module ActionMailer
4
+ class Base
5
+
6
+ def self.method_missing(method, *args)
7
+ self.new
8
+ end
9
+
10
+ def self.deliver(val = nul)
11
+ @delivered = val if val
12
+ @delivered
13
+ end
14
+ def deliver
15
+ self.class.deliver(true)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ require 'ixtlan/errors/error_dumper'
23
+ require 'date'
24
+ require 'logger'
25
+
26
+ class Controller
27
+
28
+ def request
29
+ self
30
+ end
31
+ def env
32
+ @env ||= {:one => 1, :two => 2, :three => 3}
33
+ end
34
+
35
+ def response
36
+ self
37
+ end
38
+
39
+ def headers
40
+ @headers ||= { 'ONE' => 1, "TWO" => 2 }
41
+ end
42
+
43
+ def session
44
+ @session ||= { "user" => "me" }
45
+ end
46
+
47
+ def params
48
+ @params ||= { :query => "all" }
49
+ end
50
+ end
51
+
52
+ class NilClass
53
+ def blank?
54
+ true
55
+ end
56
+ end
57
+
58
+ class String
59
+ def blank?
60
+ size == 0
61
+ end
62
+ end
63
+
64
+ class Fixnum
65
+ def ago
66
+ DateTime.now - self.to_i
67
+ end
68
+ end
69
+
70
+ class DateTime
71
+ def tv_sec
72
+ sec
73
+ end
74
+ def tv_usec
75
+ 0
76
+ end
77
+ end
78
+
79
+ describe Ixtlan::Errors::ErrorDumper do
80
+
81
+ before :each do
82
+ @dumper = Ixtlan::Errors::ErrorDumper.new
83
+ @dumper.dump_dir = "target"
84
+ @controller = Controller.new
85
+ end
86
+
87
+ 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
97
+ end
98
+
99
+ it "should clean up error dumps" do
100
+ @dumper.keep_dumps = 0
101
+ @dumper.dump(@controller, StandardError.new("dump it"))
102
+ Dir['target/error-*'].size.should == 1
103
+ @dumper.dump(@controller, StandardError.new("dump it"))
104
+ Dir['target/error-*'].size.should == 1
105
+ end
106
+
107
+ it "should send notifications" do
108
+ @dumper.email_to = "das"
109
+ @dumper.email_from = "asd"
110
+ @dumper.dump(@controller, StandardError.new("dump it"))
111
+ Ixtlan::Errors::ActionMailer::Base.delivered.should be_true
112
+ end
113
+ end
@@ -0,0 +1,138 @@
1
+ require 'ixtlan/errors/error_handler'
2
+ #require 'date'
3
+ require 'logger'
4
+
5
+ class Controller
6
+ def logger
7
+ @logger ||= Logger.new(STDOUT)
8
+ end
9
+
10
+ def respond_to(&block)
11
+ block.call self
12
+ end
13
+
14
+ def html(&block)
15
+ block.call self
16
+ end
17
+
18
+ def xml(&block)
19
+ block.call self
20
+ end
21
+
22
+ def json(&block)
23
+ block.call self
24
+ end
25
+
26
+ def stati
27
+ @stati ||= []
28
+ end
29
+
30
+ def head(status)
31
+ stati << status
32
+ end
33
+
34
+ def render(options = nil)
35
+ @render = options if options
36
+ @render
37
+ end
38
+ end
39
+
40
+ class Rails
41
+ def self.configuration
42
+ self
43
+ end
44
+
45
+ def self.error_dumper
46
+ self
47
+ end
48
+
49
+ def self.dump(controller, exception)
50
+ @dumped = exception
51
+ end
52
+
53
+ def self.dumped
54
+ r = @dumped
55
+ @dumped = nil
56
+ r
57
+ end
58
+ end
59
+
60
+ describe Ixtlan::Errors::ErrorHandler do
61
+
62
+ before :each do
63
+ @controller = Controller.new
64
+ Controller.send :include, Ixtlan::Errors::ErrorHandler
65
+ end
66
+
67
+ describe "without session" do
68
+
69
+ it "should handle internal server error" do
70
+ exp = StandardError.new("internal")
71
+ @controller.send :internal_server_error, exp
72
+ Rails.dumped.should == exp
73
+ @controller.render.should_not be_nil
74
+ @controller.render[:status].should == :internal_server_error
75
+ @controller.render[:template].should == "errors/error"
76
+ @controller.stati.should == [:internal_server_error, :internal_server_error]
77
+ end
78
+
79
+ it "should handle not found" do
80
+ exp = StandardError.new("not found")
81
+ @controller.send :page_not_found, exp
82
+ Rails.dumped.should be_nil
83
+ @controller.render.should_not be_nil
84
+ @controller.render[:status].should == :not_found
85
+ @controller.render[:template].should == "errors/error"
86
+ @controller.stati.should == [:not_found, :not_found]
87
+ end
88
+
89
+ it "should handle stale resource" do
90
+ exp = StandardError.new("stale")
91
+ @controller.send :stale_resource, exp
92
+ Rails.dumped.should be_nil
93
+ @controller.render.should_not be_nil
94
+ @controller.render[:status].should == :conflict
95
+ @controller.render[:template].should == "errors/error"
96
+ @controller.stati.should == [:conflict, :conflict]
97
+ end
98
+ end
99
+
100
+ describe "with session" do
101
+
102
+ before :each do
103
+ def @controller.current_user
104
+ Object.new
105
+ end
106
+ end
107
+
108
+ it "should handle internal server error" do
109
+ exp = StandardError.new("internal")
110
+ @controller.send :internal_server_error, exp
111
+ Rails.dumped.should == exp
112
+ @controller.render.should_not be_nil
113
+ @controller.render[:status].should == :internal_server_error
114
+ @controller.render[:template].should == "errors/error_with_session"
115
+ @controller.stati.should == [:internal_server_error, :internal_server_error]
116
+ end
117
+
118
+ it "should handle not found" do
119
+ exp = StandardError.new("not found")
120
+ @controller.send :page_not_found, exp
121
+ Rails.dumped.should be_nil
122
+ @controller.render.should_not be_nil
123
+ @controller.render[:status].should == :not_found
124
+ @controller.render[:template].should == "errors/error_with_session"
125
+ @controller.stati.should == [:not_found, :not_found]
126
+ end
127
+
128
+ it "should handle stale resource" do
129
+ exp = StandardError.new("stale")
130
+ @controller.send :stale_resource, exp
131
+ Rails.dumped.should be_nil
132
+ @controller.render.should_not be_nil
133
+ @controller.render[:status].should == :conflict
134
+ @controller.render[:template].should == "errors/error_with_session"
135
+ @controller.stati.should == [:conflict, :conflict]
136
+ end
137
+ end
138
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 0
9
- version: 0.1.0
8
+ - 1
9
+ version: 0.1.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - mkristian
@@ -14,35 +14,35 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-03-01 00:00:00 +05:30
17
+ date: 2011-03-22 00:00:00 +05:30
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: rails
21
+ name: rspec
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "="
26
26
  - !ruby/object:Gem::Version
27
27
  segments:
28
- - 3
28
+ - 2
29
+ - 4
29
30
  - 0
30
- - 1
31
- version: 3.0.1
31
+ version: 2.4.0
32
32
  type: :development
33
33
  version_requirements: *id001
34
34
  - !ruby/object:Gem::Dependency
35
- name: rspec
35
+ name: rake
36
36
  prerelease: false
37
37
  requirement: &id002 !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "="
40
40
  - !ruby/object:Gem::Version
41
41
  segments:
42
- - 2
43
42
  - 0
44
- - 1
45
- version: 2.0.1
43
+ - 8
44
+ - 7
45
+ version: 0.8.7
46
46
  type: :development
47
47
  version_requirements: *id002
48
48
  - !ruby/object:Gem::Dependency
@@ -50,29 +50,15 @@ dependencies:
50
50
  prerelease: false
51
51
  requirement: &id003 !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - "="
53
+ - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  segments:
56
56
  - 0
57
- - 9
58
- - 4
59
- version: 0.9.4
60
- type: :development
61
- version_requirements: *id003
62
- - !ruby/object:Gem::Dependency
63
- name: rake
64
- prerelease: false
65
- requirement: &id004 !ruby/object:Gem::Requirement
66
- requirements:
67
- - - "="
68
- - !ruby/object:Gem::Version
69
- segments:
70
57
  - 0
71
- - 8
72
- - 7
73
- version: 0.8.7
58
+ - 0
59
+ version: 0.0.0
74
60
  type: :development
75
- version_requirements: *id004
61
+ version_requirements: *id003
76
62
  description: dump errors on filesystem and notify developers, map different errors to specific pages
77
63
  email:
78
64
  - m.kristian@web.de
@@ -83,9 +69,6 @@ extensions: []
83
69
  extra_rdoc_files: []
84
70
 
85
71
  files:
86
- - README.textile
87
- - features/step_definitions/simple_steps.rb
88
- - features/generators.feature
89
72
  - lib/ixtlan-error-handler.rb
90
73
  - lib/ixtlan/errors/railtie.rb
91
74
  - lib/ixtlan/errors/error_handler.rb
@@ -93,10 +76,12 @@ files:
93
76
  - lib/ixtlan/errors/rescue_module.rb
94
77
  - lib/ixtlan/errors/error_dumper.rb
95
78
  - lib/ixtlan/errors/mailer/error_notification.erb
79
+ - spec/error_dumper_spec.rb
80
+ - spec/error_handler_spec.rb
96
81
  has_rdoc: true
97
82
  homepage: http://github.com/mkristian/ixtlan-error-handler
98
- licenses: []
99
-
83
+ licenses:
84
+ - MIT-LICENSE
100
85
  post_install_message:
101
86
  rdoc_options:
102
87
  - --main
@@ -124,5 +109,6 @@ rubygems_version: 1.3.6
124
109
  signing_key:
125
110
  specification_version: 3
126
111
  summary: dump errors on filesystem and notify developers
127
- test_files: []
128
-
112
+ test_files:
113
+ - spec/error_dumper_spec.rb
114
+ - spec/error_handler_spec.rb
data/README.textile DELETED
@@ -1,31 +0,0 @@
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,5 +0,0 @@
1
- Feature: Generators for Ixtlan Audit
2
-
3
- Scenario: The slf4r rails template creates a rails application which uses slf4r-wrapper
4
- Given I create new rails application with template "simple.template"
5
- Then the output should contain "setup slf4r logger wrapper with ActiveSupport::BufferedLogger"
@@ -1,22 +0,0 @@
1
- require 'fileutils'
2
- Given /^I create new rails application with template "(.*)"$/ do |template|
3
- name = template.sub(/.template$/, '')
4
- directory = File.join('target', name)
5
- rails_version = ENV['RAILS_VERSION'] || '3.0.1'
6
-
7
- ruby = defined?(JRUBY_VERSION) ? "jruby" : "ruby"
8
- rails_command = "#{ENV['GEM_HOME']}/bin/rails"
9
- rails_command = "-S rails" unless File.exists?(rails_command)
10
- command = "#{rails_command} _#{rails_version}_ new #{directory} -f -m templates/#{template}"
11
- FileUtils.rm_rf(directory)
12
-
13
- system "#{ruby} #{command}"
14
-
15
- @result = File.read("target/#{name}/log/development.log")
16
- puts @result
17
- end
18
-
19
- Then /^the output should contain \"(.*)\"$/ do |expected|
20
- (@result =~ /.*#{expected}.*/).should_not be_nil
21
- end
22
-