ixtlan-error-handler 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -1,5 +1,11 @@
1
1
  h1. Rails Error Dumper
2
2
 
3
+ * "!https://secure.travis-ci.org/mkristian/ixtlan-error-handler.png!":http://travis-ci.org/mkristian/ixtlan-error-handler
4
+
5
+ * "!https://gemnasium.com/mkristian/ixtlan-error-handler.png!":https://gemnasium.com/mkristian/ixtlan-error-handler
6
+
7
+ * "!https://codeclimate.com/badge.png!":https://codeclimate.com/github/mkristian/ixtlan-error-handler
8
+
3
9
  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
10
 
5
11
  * 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
@@ -0,0 +1,37 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ require 'cuba_api'
22
+ require 'ixtlan/errors/resource'
23
+ require 'ixtlan/errors/serializer'
24
+ module Ixtlan
25
+ module Errors
26
+ class Cuba < ::CubaAPI
27
+ define do
28
+ on get, :number do |number|
29
+ write Ixtlan::Errors::Error.get!( number )
30
+ end
31
+ on get do
32
+ write Ixtlan::Errors::Error.all.reverse
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ #require 'cuba_api'
2
+ require 'ixtlan/audit/resource'
3
+ module Ixtlan
4
+ module Audit
5
+ class Cuba < ::CubaAPI
6
+ define do
7
+ on default do
8
+ write Ixtlan::Audit::Audit.all.reverse
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,146 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ require 'ixtlan/errors/mailer'
22
+ require 'fileutils'
23
+
24
+ module Ixtlan
25
+ module Errors
26
+ class Dumper
27
+
28
+ private
29
+
30
+ if defined? ::Slf4r
31
+ include ::Slf4r::Logger
32
+ else
33
+ require 'logger'
34
+ def logger
35
+ @logger ||= Logger.new( STDOUT )
36
+ end
37
+ end
38
+
39
+ public
40
+
41
+ attr_accessor :model, :block, :from_email, :to_emails, :keep_dumps, :base_url
42
+
43
+ def initialize( model = nil, &block )
44
+ @model = model
45
+ @keep_dumps = 30
46
+ block.call( self ) if block
47
+ @block = block
48
+ end
49
+
50
+ def model
51
+ @model ||= (Ixtlan::Errors::Error rescue nil)
52
+ end
53
+
54
+ def keep_dumps=(ttl)
55
+ old = @keep_dumps
56
+ @keep_dumps = ttl.to_i
57
+ daily_cleanup if old != @keep_dumps
58
+ end
59
+
60
+ def dump( exception, request, response, session , params )
61
+ update_config
62
+
63
+ daily_cleanup
64
+
65
+ error = dump_environment( exception,
66
+ request,
67
+ response,
68
+ session,
69
+ params )
70
+
71
+ if not @to_emails.blank? and not @from_email.blank?
72
+ Mailer.error_notification( @from_email,
73
+ @to_emails,
74
+ exception,
75
+ "#{@base_url}/#{error.id}" ).deliver
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ def update_config
82
+ block.call( self ) if block
83
+ end
84
+
85
+ def dump_environment( exception, request, response, session , params )
86
+ dump = model.new
87
+
88
+ dump.request = dump_hashmap( request )
89
+
90
+ dump.response = dump_hashmap( response )
91
+
92
+ dump.session = dump_hashmap( session )
93
+
94
+ dump.parameters = dump_hashmap( params )
95
+
96
+ dump.message = exception.message
97
+
98
+ dump.clazz = exception.class.to_s
99
+
100
+ dump.backtrace = exception.backtrace.join("\n") if exception.backtrace
101
+
102
+ dump if dump.save
103
+ end
104
+
105
+ def dump_hashmap(map, indent = '')
106
+ result = ''
107
+ map.each do |key,value|
108
+ if value.is_a? Hash
109
+ result << "#{indent}#{key} => {\n"
110
+ result << dump_hashmap(value, "#{indent} ")
111
+ result << "#{indent}}\n"
112
+ else
113
+ result << "#{indent}#{key} => #{value.nil? ? 'nil': value}\n"
114
+ end
115
+ end
116
+ result
117
+ end
118
+
119
+ def daily_cleanup
120
+ return unless model
121
+ now = DateTime.now
122
+ if(@last_cleanup.nil? || @last_cleanup < (now - 1))
123
+ @last_cleanup = now
124
+ begin
125
+ delete_all( now - keep_logs )
126
+ logger.info "cleaned error dumps"
127
+ rescue Exception => e
128
+ logger.warn "error cleaning up error dumps: #{e.message}"
129
+ end
130
+ end
131
+ end
132
+
133
+ private
134
+
135
+ if defined? ::DataMapper
136
+ def delete_all( expired )
137
+ model.all( :created_at.lte => expired ).destroy!
138
+ end
139
+ else # ActiveRecord
140
+ def delete_all( expired )
141
+ model.all( :conditions => ["created_at <= ?", expired] ).each(&:delete)
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,152 @@
1
+ #
2
+ # Copyright (C) 2012 mkristian
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ require 'ixtlan/errors/mailer'
22
+ require 'fileutils'
23
+
24
+ module Ixtlan
25
+ module Errors
26
+ class ErrorDumper
27
+
28
+ private
29
+
30
+ if defined? ::Slf4r
31
+ include ::Slf4r::Logger
32
+ else
33
+ require 'logger'
34
+ def logger
35
+ @logger ||= Logger.new( STDOUT )
36
+ end
37
+ end
38
+
39
+ public
40
+
41
+ attr_accessor :model, :block, :from_email, :to_emails, :keep_dumps, :base_url, :dump_to_console
42
+
43
+ def initialize( model = nil, &block )
44
+ @model = model
45
+ @keep_dumps = 30
46
+ @dump_to_console = false
47
+ block.call( self ) if block
48
+ @block = block
49
+ end
50
+
51
+ def model
52
+ @model ||= (Ixtlan::Errors::Error rescue nil)
53
+ end
54
+
55
+ def keep_dumps=(ttl)
56
+ old = @keep_dumps
57
+ @keep_dumps = ttl.to_i
58
+ daily_cleanup if old != @keep_dumps
59
+ end
60
+
61
+ def dump( exception, request, response, session , params )
62
+ update_config
63
+
64
+ daily_cleanup
65
+
66
+ error = dump_environment( exception,
67
+ request,
68
+ response,
69
+ session,
70
+ params )
71
+
72
+ if @dump_to_console
73
+ logger.warn error.to_s
74
+ trace = ( error.backtrace || [] ).join( "\n\t" )
75
+ logger.warn "#{trace}"
76
+ end
77
+ if not @to_emails.blank? and not @from_email.blank?
78
+ Mailer.error_notification( @from_email,
79
+ @to_emails,
80
+ exception,
81
+ "#{@base_url}/#{error.id}" ).deliver
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def update_config
88
+ block.call( self ) if block
89
+ end
90
+
91
+ def dump_environment( exception, request, response, session , params )
92
+ dump = error_dump_model.new
93
+
94
+ dump.request = dump_hashmap( request )
95
+
96
+ dump.response = dump_hashmap( response )
97
+
98
+ dump.session = dump_hashmap( session )
99
+
100
+ dump.parameters = dump_hashmap( params )
101
+
102
+ dump.message = exception.message
103
+
104
+ dump.clazz = exception.class.to_s
105
+
106
+ dump.backtrace = exception.backtrace.join("\n") if exception.backtrace
107
+
108
+ dump if dump.save
109
+ end
110
+
111
+ def dump_hashmap(map, indent = '')
112
+ result = ''
113
+ map.each do |key,value|
114
+ if value.is_a? Hash
115
+ result << "#{indent}#{key} => {\n"
116
+ result << dump_hashmap(value, "#{indent} ")
117
+ result << "#{indent}}\n"
118
+ else
119
+ result << "#{indent}#{key} => #{value.nil? ? 'nil': value}\n"
120
+ end
121
+ end
122
+ result
123
+ end
124
+
125
+ def daily_cleanup
126
+ return unless model
127
+ now = DateTime.now
128
+ if(@last_cleanup.nil? || @last_cleanup < (now - 1))
129
+ @last_cleanup = now
130
+ begin
131
+ delete_all( now - keep_logs )
132
+ logger.info "cleaned error dumps"
133
+ rescue Exception => e
134
+ logger.warn "error cleaning up error dumps: #{e.message}"
135
+ end
136
+ end
137
+ end
138
+
139
+ private
140
+
141
+ if defined? ::DataMapper
142
+ def delete_all( expired )
143
+ model.all( :created_at.lte => expired ).destroy!
144
+ end
145
+ else # ActiveRecord
146
+ def delete_all( expired )
147
+ model.all( :conditions => ["created_at <= ?", expired] ).each(&:delete)
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,17 @@
1
+ class Error
2
+
3
+ include DataMapper::Resource
4
+
5
+ property :id, Serial
6
+
7
+ property :message, String, :required => true, :length => 255
8
+ property :request, Text, :required => true, :length => 64536
9
+ property :response, Text, :required => true, :length => 32768
10
+ property :session, Text, :required => true, :length => 16384
11
+ property :parameters, Text, :required => true, :length => 32768
12
+ property :clazz, String, :required => true, :length => 64
13
+ property :backtrace, Text, :required => true, :length => 32768
14
+
15
+ timestamps :at
16
+
17
+ end
@@ -1,3 +1,23 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
1
21
  module Ixtlan
2
22
  module Errors
3
23
  module ErrorHandler
@@ -61,8 +81,12 @@ module Ixtlan
61
81
  end
62
82
 
63
83
  def dump_error(exception)
64
- Rails.configuration.error_dumper.dump(self, exception)
84
+ Rails.configuration.error_dumper.dump( exception,
85
+ controller.request.env,
86
+ controller.response.headers,
87
+ controller.session,
88
+ controller.params )
65
89
  end
66
90
  end
67
91
  end
68
- end
92
+ end
@@ -0,0 +1,14 @@
1
+ require 'ixtlan/babel/serializer'
2
+
3
+ class ErrorSerializer < Ixtlan::Babel::Serializer
4
+
5
+ model Error
6
+
7
+ root 'error'
8
+
9
+ add_context(:single )
10
+
11
+ add_context(:collection,
12
+ :except => [:created_at]
13
+ )
14
+ end
@@ -1,15 +1,62 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ begin
22
+ require 'pony'
23
+ rescue LoadError
24
+ # let's assume ActionMailer instead
25
+ end
26
+
1
27
  module Ixtlan
2
28
  module Errors
3
- class Mailer < ActionMailer::Base
29
+ if defined? Pony
30
+
31
+ class Deliver < Proc
32
+ def deliver
33
+ call
34
+ end
35
+ end
36
+
37
+ class Mailer
38
+ def self.error_notification(email_from, emails_to, exception, error_url)
39
+ Deliver.new do
40
+ Pony.mail( :from => email_from,
41
+ :to => emails_to,
42
+ :subject => exception.message,
43
+ :body => "#{error_url}" )
44
+ end
45
+ end
46
+ end
47
+
48
+ else
49
+ class Mailer < ActionMailer::Base
4
50
 
5
- def error_notification(email_from, emails_to, exception, error_url)
6
- @subject = exception.message
7
- @text = "#{error_url}"
8
- @recipients = emails_to
9
- @from = email_from
10
- @sent_on = Time.now
11
- @headers = {}
51
+ def error_notification(email_from, emails_to, exception, error_url)
52
+ @subject = exception.message
53
+ @text = "#{error_url}"
54
+ @recipients = emails_to
55
+ @from = email_from
56
+ @sent_on = Time.now
57
+ @headers = {}
58
+ end
12
59
  end
13
60
  end
14
61
  end
15
- end
62
+ end
@@ -0,0 +1,79 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ module Ixtlan
22
+ module Errors
23
+ class Rack
24
+
25
+ DEFAULT_MAP = {}
26
+
27
+ # conflict
28
+ DEFAULT_MAP[ 409 ] = []
29
+ if defined? ::Ixtlan::Optimistic
30
+ DEFAULT_MAP[ 409 ] << ::Ixtlan::Optimistic::ObjectStaleException
31
+ end
32
+
33
+ # not found
34
+ DEFAULT_MAP[ 404 ] = []
35
+ if defined? ::Ixtlan::Guard
36
+ DEFAULT_MAP[ 404 ] << ::Ixtlan::Guard::GuardException
37
+ DEFAULT_MAP[ 404 ] << ::Ixtlan::Guard::PermissionDenied
38
+ end
39
+ if defined? ::DataMapper
40
+ DEFAULT_MAP[ 404 ] << ::DataMapper::ObjectNotFoundError
41
+ end
42
+ if defined? ::ActiveRecord
43
+ DEFAULT_MAP[ 404 ] << ::ActiveRecord::RecordNotFound
44
+ end
45
+
46
+ def initialize(app, dumper, dump_to_console = false, map = {} )
47
+ @app = app
48
+ @dumper = dumper
49
+ @dump_to_console = dump_to_console
50
+ @map = {}
51
+ DEFAULT_MAP.each do |status, list|
52
+ list.each { |exp| @map[ exp ] = status }
53
+ end
54
+ map.each do |status, list|
55
+ list.each { |exp| @map[ exp ] = status }
56
+ end
57
+ end
58
+
59
+ def call(env)
60
+ begin
61
+ @app.call(env)
62
+ rescue Exception => e
63
+ status = @map[ e.class ] || 500
64
+ if status >= 500
65
+ @dumper.dump( e, env, {}, {}, {} )
66
+ end
67
+ if @dump_to_console
68
+ warn "[Ixtlan] #{e.class}: #{e.message}"
69
+ warn "\t" + e.backtrace.join( "\n\t" ) if e.backtrace && status >= 500
70
+ end
71
+ [ status,
72
+ {'Content-Type' => 'text/plain'},
73
+ [''] ]
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,53 @@
1
+ module Ixtlan
2
+ module Errors
3
+ class Rack
4
+
5
+ DEFAULT_MAP = {}
6
+
7
+ # conflict
8
+ DEFAULT_MAP[ 409 ] = []
9
+ if defined? ::Ixtlan::Optimistic
10
+ DEFAULT_MAP[ 409 ] << ::Ixtlan::Optimistic::ObjectStaleException
11
+ end
12
+
13
+ # not found
14
+ DEFAULT_MAP[ 404 ] = []
15
+ if defined? ::Ixtlan::Guard
16
+ DEFAULT_MAP[ 404 ] << ::Ixtlan::Guard::GuardException
17
+ DEFAULT_MAP[ 404 ] << ::Ixtlan::Guard::PermissionDenied
18
+ end
19
+ if defined? ::DataMapper
20
+ DEFAULT_MAP[ 404 ] << ::DataMapper::ObjectNotFoundError
21
+ end
22
+ if defined? ::ActiveRecord
23
+ DEFAULT_MAP[ 404 ] << ::ActiveRecord::RecordNotFound
24
+ end
25
+
26
+ def initialize(app, dumper, dump_to_console = false, map = {} )
27
+ @app = app
28
+ @dumper = dumper
29
+ @dump_to_console = dump_to_console
30
+ @map = DEFAULT_MAP.dup
31
+ map.each do |status, list|
32
+ list.each { |exp| @map[ exp ] = status }
33
+ end
34
+ end
35
+
36
+ def call(env)
37
+ begin
38
+ @app.call(env)
39
+ rescue Exception => e
40
+ @dumper.dump( e, env, {}, {}, {} )
41
+ if @dump_to_console
42
+ warn "#{e.class}: #{e.message}"
43
+ warn "\t" + e.backtrace.join( "\n\t" ) if e.backtrace
44
+ end
45
+ [ @map[ e.class ] || 500,
46
+ {'Content-Type' => 'text/plain'},
47
+ [''] ]
48
+ end
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -1,20 +1,45 @@
1
- require 'rails'
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ begin
22
+ require 'pony'
23
+ rescue LoadError
24
+ # ignore
25
+ end
2
26
  require 'ixtlan/errors/rescue_module'
3
27
  require 'ixtlan/errors/error_handler'
4
- require 'ixtlan/errors/error_dumper'
5
-
28
+ require 'ixtlan/errors/dumper'
6
29
  module Ixtlan
7
30
  module Errors
8
31
  class Railtie < Rails::Railtie
9
32
 
10
33
  config.before_configuration do |app|
11
-
12
- path = File.join(File.dirname(__FILE__), "..", "..")
13
- unless ActionMailer::Base.view_paths.member? path
14
- ActionMailer::Base.view_paths= [ActionMailer::Base.view_paths, path].flatten
34
+
35
+ unless defined? Pony
36
+ path = File.join(File.dirname(__FILE__), "..", "..")
37
+ unless ActionMailer::Base.view_paths.member? path
38
+ ActionMailer::Base.view_paths= [ActionMailer::Base.view_paths, path].flatten
39
+ end
15
40
  end
16
41
 
17
- app.config.error_dumper = ErrorDumper.new
42
+ app.config.error_dumper = Dumper.new
18
43
  app.config.skip_rescue_module = false
19
44
  end
20
45
 
@@ -24,4 +49,4 @@ module Ixtlan
24
49
  end
25
50
  end
26
51
  end
27
- end
52
+ end
@@ -1,3 +1,23 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
1
21
  module Ixtlan
2
22
  module Errors
3
23
  module RescueModule
@@ -6,6 +26,10 @@ module Ixtlan
6
26
  # needs 'optimistic_persistence'
7
27
  controller.rescue_from ::Ixtlan::ModifiedBy::StaleResourceError, :with => :stale_resource
8
28
  end
29
+ if defined? ::Ixtlan::Optimistic
30
+ # needs 'optimistic_persistence'
31
+ controller.rescue_from ::Ixtlan::Optimistic::ObjectStaleException, :with => :stale_resource
32
+ end
9
33
 
10
34
  if defined? ::Ixtlan::Guard
11
35
  # needs 'guard'
@@ -25,7 +49,12 @@ module Ixtlan
25
49
 
26
50
  # standard rails controller
27
51
  controller.rescue_from ::ActionController::RoutingError, :with => :page_not_found
28
- controller.rescue_from ::ActionController::UnknownAction, :with => :page_not_found
52
+
53
+ if defined? ::AbstractController::ActionNotFound
54
+ controller.rescue_from ::AbstractController::ActionNotFound, :with => :page_not_found
55
+ else
56
+ controller.rescue_from ::ActionController::UnknownAction, :with => :page_not_found
57
+ end
29
58
  controller.rescue_from ::ActionController::MethodNotAllowed, :with => :page_not_found
30
59
  controller.rescue_from ::ActionController::NotImplemented, :with => :page_not_found
31
60
  controller.rescue_from ::ActionController::InvalidAuthenticityToken, :with => :stale_resource
@@ -39,4 +68,4 @@ module Ixtlan
39
68
  end
40
69
  end
41
70
  end
42
- end
71
+ end
@@ -0,0 +1,45 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ require 'dm-core'
22
+ module Ixtlan
23
+ module Errors
24
+ class Error
25
+
26
+ include DataMapper::Resource
27
+
28
+ property :id, Serial
29
+
30
+ property :clazz, String, :required => true, :length => 64
31
+ property :message, String, :required => true, :length => 255
32
+ property :backtrace, Text, :required => true, :length => 32768
33
+ property :request, Text, :required => true, :length => 64536
34
+ property :response, Text, :required => true, :length => 32768
35
+ property :session, Text, :required => true, :length => 16384
36
+ property :parameters, Text, :required => true, :length => 32768
37
+
38
+ property :created_at, DateTime
39
+
40
+ before :save do
41
+ self.created_at = DateTime.now
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,24 @@
1
+ module Ixtlan
2
+ module Errors
3
+ class Error
4
+
5
+ include DataMapper::Resource
6
+
7
+ property :id, Serial
8
+
9
+ property :clazz, String, :required => true, :length => 64
10
+ property :message, String, :required => true, :length => 255
11
+ property :backtrace, Text, :required => true, :length => 32768
12
+ property :request, Text, :required => true, :length => 64536
13
+ property :response, Text, :required => true, :length => 32768
14
+ property :session, Text, :required => true, :length => 16384
15
+ property :parameters, Text, :required => true, :length => 32768
16
+
17
+ property :created_at, DateTime
18
+
19
+ before :save do
20
+ self.created_at = DateTime.now
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ require 'ixtlan/babel/serializer'
22
+
23
+ module Ixtlan
24
+ module Errors
25
+
26
+ class ErrorSerializer < Ixtlan::Babel::Serializer
27
+
28
+ root 'error'
29
+
30
+ add_context( :single )
31
+
32
+ add_context( :collection, :only => [ :id, :clazz, :message ] )
33
+
34
+ end
35
+ end
36
+ end
@@ -1,3 +1,23 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
1
21
  if defined?(Rails)
2
22
  require 'ixtlan/errors/railtie'
3
23
  end
metadata CHANGED
@@ -1,142 +1,158 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ixtlan-error-handler
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
4
5
  prerelease:
5
- version: 0.2.0
6
6
  platform: ruby
7
- authors:
8
- - mkristian
7
+ authors:
8
+ - Christian Meier
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-11-04 00:00:00 +05:30
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
17
- name: slf4r
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
20
- none: false
21
- requirements:
22
- - - ~>
23
- - !ruby/object:Gem::Version
24
- version: 0.4.2
25
- type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: rspec
29
- prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
31
- none: false
32
- requirements:
33
- - - "="
34
- - !ruby/object:Gem::Version
35
- version: 2.6.0
36
- type: :development
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: rake
40
- prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
42
- none: false
43
- requirements:
44
- - - "="
45
- - !ruby/object:Gem::Version
46
- version: 0.8.7
47
- type: :development
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
82
- description: dump errors on filesystem and notify developers, map different errors to specific pages
83
- email:
84
- - m.kristian@web.de
12
+ date: 2012-12-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: slf4r
16
+ requirement: &13017120 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.4.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *13017120
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &13014420 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '2.11'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *13014420
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &13013760 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 10.0.2
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *13013760
47
+ - !ruby/object:Gem::Dependency
48
+ name: dm-core
49
+ requirement: &13013000 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.2.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *13013000
58
+ - !ruby/object:Gem::Dependency
59
+ name: dm-migrations
60
+ requirement: &13012260 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.2.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *13012260
69
+ - !ruby/object:Gem::Dependency
70
+ name: dm-sqlite-adapter
71
+ requirement: &13011800 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.2.0
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *13011800
80
+ - !ruby/object:Gem::Dependency
81
+ name: copyright-header
82
+ requirement: &13011240 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: 1.0.7
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *13011240
91
+ description: dump errors on filesystem and notify developers, map different errors
92
+ to specific pages
93
+ email:
94
+ - m.kristian@web.de
85
95
  executables: []
86
-
87
96
  extensions: []
88
-
89
97
  extra_rdoc_files: []
90
-
91
- files:
92
- - MIT-LICENSE
93
- - README.textile
94
- - lib/ixtlan-error-handler.rb
95
- - lib/ixtlan/errors/error_dumper.rb
96
- - lib/ixtlan/errors/mailer.rb
97
- - lib/ixtlan/errors/error_handling.rb~
98
- - lib/ixtlan/errors/rescue_module.rb~
99
- - lib/ixtlan/errors/rescue_module.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~
106
- - lib/ixtlan/errors/mailer/error_notification.erb
107
- - spec/error_handler_spec.rb
108
- - spec/error_dumper_spec.rb~
109
- - spec/error_handler_spec.rb~
110
- - spec/error_dumper_spec.rb
111
- has_rdoc: true
98
+ files:
99
+ - MIT-LICENSE
100
+ - README.textile
101
+ - lib/ixtlan-error-handler.rb
102
+ - lib/ixtlan/errors/cuba.rb~
103
+ - lib/ixtlan/errors/mailer.rb
104
+ - lib/ixtlan/errors/cuba.rb
105
+ - lib/ixtlan/errors/dumper.rb
106
+ - lib/ixtlan/errors/error_handling.rb~
107
+ - lib/ixtlan/errors/mailer/error_notification.erb
108
+ - lib/ixtlan/errors/error.rb~
109
+ - lib/ixtlan/errors/resource.rb~
110
+ - lib/ixtlan/errors/rescue_module.rb~
111
+ - lib/ixtlan/errors/resource.rb
112
+ - lib/ixtlan/errors/error_serializer.rb~
113
+ - lib/ixtlan/errors/dumper.rb~
114
+ - lib/ixtlan/errors/rescue_module.rb
115
+ - lib/ixtlan/errors/error_dumper.rb~
116
+ - lib/ixtlan/errors/error_handler.rb~
117
+ - lib/ixtlan/errors/railtie.rb~
118
+ - lib/ixtlan/errors/error_handler.rb
119
+ - lib/ixtlan/errors/railtie.rb
120
+ - lib/ixtlan/errors/mailer.rb~
121
+ - lib/ixtlan/errors/rack.rb~
122
+ - lib/ixtlan/errors/rack.rb
123
+ - lib/ixtlan/errors/serializer.rb
124
+ - spec/error_handler_spec.rb
125
+ - spec/error_dumper_spec.rb~
126
+ - spec/error_handler_spec.rb~
127
+ - spec/error_dumper_spec.rb
112
128
  homepage: http://github.com/mkristian/ixtlan-error-handler
113
- licenses:
114
- - MIT-LICENSE
129
+ licenses:
130
+ - MIT
115
131
  post_install_message:
116
- rdoc_options:
117
- - --main
118
- - README.textile
119
- require_paths:
120
- - lib
121
- required_ruby_version: !ruby/object:Gem::Requirement
132
+ rdoc_options:
133
+ - --main
134
+ - README.textile
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
122
138
  none: false
123
- requirements:
124
- - - ">="
125
- - !ruby/object:Gem::Version
126
- version: "0"
127
- required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
144
  none: false
129
- requirements:
130
- - - ">="
131
- - !ruby/object:Gem::Version
132
- version: "0"
145
+ requirements:
146
+ - - ! '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
133
149
  requirements: []
134
-
135
150
  rubyforge_project:
136
- rubygems_version: 1.5.1
151
+ rubygems_version: 1.8.11
137
152
  signing_key:
138
153
  specification_version: 3
139
154
  summary: dump errors on filesystem and notify developers
140
- test_files:
141
- - spec/error_handler_spec.rb
142
- - spec/error_dumper_spec.rb
155
+ test_files:
156
+ - spec/error_handler_spec.rb
157
+ - spec/error_dumper_spec.rb
158
+ has_rdoc:
@@ -1,112 +0,0 @@
1
- require 'ixtlan/errors/mailer'
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
16
-
17
- module Ixtlan
18
- module Errors
19
- class ErrorDumper
20
-
21
- private
22
-
23
- include ::Slf4r::Logger
24
-
25
- public
26
-
27
- attr_accessor :from_email, :to_emails, :keep_dumps, :base_url
28
-
29
- def initialize
30
- @keep_dumps = 30
31
- end
32
-
33
- def keep_dumps=(ttl)
34
- old = @keep_dumps
35
- @keep_dumps = ttl.to_i
36
- daily_cleanup if old != @keep_dumps
37
- end
38
-
39
- def error_dump_model(model = nil)
40
- @error_dump ||= model.nil? ? ::Error : model.classify
41
- end
42
-
43
- def dump(controller, exception)
44
- daily_cleanup
45
-
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}"
49
- end
50
-
51
- private
52
-
53
- def dump_environment(exception, controller)
54
- dump = error_dump_model.new
55
-
56
- dump.request = dump_hashmap(controller.request.env)
57
-
58
- dump.response = dump_hashmap(controller.response.headers)
59
-
60
- dump.session = dump_hashmap(controller.session)
61
-
62
- dump.parameters = dump_hashmap(controller.params)
63
-
64
- dump.message = exception.message
65
-
66
- dump.clazz = exception.class.to_s
67
-
68
- dump.backtrace = exception.backtrace.join("\n") if exception.backtrace
69
-
70
- dump if dump.save
71
- end
72
-
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
85
- end
86
-
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
96
- end
97
- end
98
-
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)
108
- end
109
- end
110
- end
111
- end
112
- end