exception_no 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OGYwNDYzMDA0NmQzN2U4YTU2MGYxMzQ3OTQ5YTY5NTQ5Y2JiNTExNA==
4
+ NDMwNTRkNzExMWNiOWQ0OGQ5NzFmYmJhYmM2MTBhNGYzMWZiZWZkMg==
5
5
  data.tar.gz: !binary |-
6
- NWY4ODFiOGIwNDI3YzcwZjBkOGE3YjE0ZGY4NTQ3MzEzNDM5ZDM2OQ==
6
+ NTY4YmJhNjUzZWU5YTJjMmUyODI5M2ZiMTVkYTZmOGJmNWE2MWIwNw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- N2Q3NWE4ZGEyZDI4NTg4MTA5Y2ZkMTQ0MmU4MWQyODUxMzAyMzYwZTk3ZjFm
10
- NjBhZTFmZTcxMTg4M2JjN2NlZjEwNzAyZGNiNTQyMGI4MmNhNzEzMzBiMDQ4
11
- YzRlYjI1ZGVkNzBkMzM0MTUzYzFkY2I3YzZhYjk4NjRhMDFkMDc=
9
+ MDI3ZTY2NjhkYjk2NjU3ODZmNGNhNTMyNjczZDUwYWRiZDE1NmFmZjdhOWI4
10
+ YWNjYmIzYjAyMGM5MzhmOTdkMWUyMGYyNGIwNjFlMzQxMWJlMTUxMzU1ZTYx
11
+ NTU2YTc2NDY5NDBmNzAzN2I4M2RjNjlhYzA4YWY2MDUwODFkMzU=
12
12
  data.tar.gz: !binary |-
13
- MWI4YWI5MzQwNTU3ZjNiYzZjYmU1ZDBhNjUwNDkxYmIwMTI3OGMzNDJiYTgz
14
- Y2Y3ZDk5OGQzYTU3OTViNmNiMTc2MGUyODBjY2MxYzFjOTNmNTMyY2UwYzhl
15
- ZjBlYjJkMGM2MmFjMmQ0MmNhMDQ5NWFhOTZkMGMxNjU0MWEyZDk=
13
+ M2RmMjc2ZjQyNjg1MzRlN2M0OTUyNDY1MTVjNjM2ODNjZjk4ZjNmNmZjNTU5
14
+ NzFlYjU0ODNkZmY1NjNiMDVkYzdkNzkwZWVhYzBhMjdmNzY1Y2NhM2E0YjE2
15
+ ZDkxMmZjMDgyOTFhYjY4MTAzNzM4NDYzZmYyYmFlMWY5NzBiYWI=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ 0.0.5 - 2014-09-10
2
+ ==================
3
+
4
+ * The middleware now extracts the request IP address.
5
+
6
+ * The middleware now extracts the request body.
7
+
8
+ * Added `ExceptionNo#run` which takes a block and notifies about errors.
9
+
1
10
  0.0.3 - 2013-09-18
2
11
  ==================
3
12
 
data/exception_no.gemspec CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |s|
13
13
 
14
14
  s.license = "Unlicense"
15
15
 
16
- s.add_development_dependency "mini-smtp-server"
17
16
  s.add_development_dependency "cutest"
17
+ s.add_development_dependency "mini-smtp-server"
18
+ s.add_development_dependency "rack"
18
19
  end
data/lib/exception_no.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  require "net/smtp"
2
2
  require "erb"
3
+ require "pp"
3
4
 
4
5
  class ExceptionNo
5
- VERSION = "0.0.4"
6
+ VERSION = "0.0.5"
6
7
 
7
8
  attr_accessor :backtrace_filter
8
9
  attr_accessor :behaviors
@@ -15,7 +16,7 @@ class ExceptionNo
15
16
  @backtrace_filter = -> line { true }
16
17
  end
17
18
 
18
- def _deliver(exception, options = {})
19
+ def _deliver(exception, env = {})
19
20
  body = @template.result(binding)
20
21
 
21
22
  Net::SMTP.start(@config.fetch(:host), @config.fetch(:port, 25)) do |smtp|
@@ -42,12 +43,20 @@ class ExceptionNo
42
43
  raise exception if @behaviors.include?(:raise)
43
44
  end
44
45
 
46
+ def run(env = {})
47
+ begin
48
+ yield
49
+ rescue Exception => ex
50
+ notify(ex, env)
51
+ end
52
+ end
53
+
45
54
  TEMPLATE = (<<-'EMAIL').gsub(/^ {2}/, '')
46
55
  From: <%= @config[:from_alias] %> <<%= @config[:from] %>>
47
56
  To: <<%= @config[:to] %>>
48
57
  Subject: <%= exception.class %>: <%= exception.message.split.join(" ") %>
49
58
 
50
- <%= options[:body] %>
59
+ <%= env.map { |*parts| parts.join(": ") }.join("\n") %>
51
60
 
52
61
  <%= "~" * 80 %>
53
62
 
@@ -66,7 +75,7 @@ class ExceptionNo
66
75
  begin
67
76
  @app.call(env)
68
77
  rescue Exception => e
69
- @notifier.notify(e, body: extract_env(env))
78
+ @notifier.notify(e, extract_env(env))
70
79
 
71
80
  raise e
72
81
  end
@@ -80,9 +89,24 @@ class ExceptionNo
80
89
  parts << "#{req.request_method} #{req.url}"
81
90
  parts << "User-Agent: #{req.user_agent}" if req.user_agent
82
91
  parts << "Referrer: #{req.referrer}" if req.referrer
92
+ parts << "IP: #{req.ip}" if req.ip
83
93
  parts << "Cookie: #{req.env["HTTP_COOKIE"]}" if req.cookies.size > 0
84
94
 
85
- parts.join("\n")
95
+ if req.form_data?
96
+ body = req.POST.pretty_inspect
97
+ else
98
+ req.body.rewind
99
+
100
+ body = req.body.read
101
+
102
+ body = nil if body.empty?
103
+ end
104
+
105
+ if body
106
+ parts << "Body: \n#{body.gsub(/^/, " ")}"
107
+ end
108
+
109
+ parts
86
110
  end
87
111
  end
88
112
  end
data/test/exception_no.rb CHANGED
@@ -16,7 +16,7 @@ test "deliver exception notification" do |notifier|
16
16
 
17
17
  notifier.notify(ex)
18
18
 
19
- email = $smtp.outbox.last
19
+ email = $smtp.outbox.pop
20
20
 
21
21
  assert_equal email[:to], "<root@localhost>"
22
22
  assert_equal email[:from], "<service@localhost>"
@@ -32,7 +32,7 @@ test "exception messages with multiple lines" do |notifier|
32
32
 
33
33
  notifier.notify(ArgumentError.new("A really\nbad\nargument"))
34
34
 
35
- headers, body = parse_email($smtp.outbox.last[:data])
35
+ headers, body = parse_email($smtp.outbox.pop[:data])
36
36
 
37
37
  assert_equal headers["Subject"], "ArgumentError: A really bad argument"
38
38
  end
@@ -46,7 +46,7 @@ test "includes backtrace information" do |notifier|
46
46
  notifier.notify(ex)
47
47
  end
48
48
 
49
- headers, body = parse_email($smtp.outbox.last[:data])
49
+ headers, body = parse_email($smtp.outbox.pop[:data])
50
50
 
51
51
  assert body.include?(__FILE__)
52
52
  assert body.include?(Gem.path.first)
@@ -65,7 +65,7 @@ test "allows to filter the backtrace" do |notifier|
65
65
  notifier.notify(ex)
66
66
  end
67
67
 
68
- headers, body = parse_email($smtp.outbox.last[:data])
68
+ headers, body = parse_email($smtp.outbox.pop[:data])
69
69
 
70
70
  assert body.include?(__FILE__)
71
71
  assert !body.include?(Gem.path.first)
@@ -76,7 +76,9 @@ test "disable delivery" do |notifier|
76
76
 
77
77
  notifier.notify(ArgumentError.new)
78
78
 
79
- assert_equal $smtp.outbox.size, 0
79
+ assert_raise(QueueWithTimeout::Timeout) do
80
+ $smtp.outbox.pop(0.5)
81
+ end
80
82
  end
81
83
 
82
84
  test "raise exception" do |notifier|
@@ -84,7 +86,9 @@ test "raise exception" do |notifier|
84
86
 
85
87
  assert_raise(ArgumentError) { notifier.notify(ArgumentError.new) }
86
88
 
87
- assert_equal $smtp.outbox.size, 0
89
+ assert_raise(QueueWithTimeout::Timeout) do
90
+ $smtp.outbox.pop(0.5)
91
+ end
88
92
  end
89
93
 
90
94
  test "raise exception and deliver notification" do |notifier|
@@ -92,8 +96,27 @@ test "raise exception and deliver notification" do |notifier|
92
96
 
93
97
  assert_raise(ArgumentError) { notifier.notify(ArgumentError.new) }
94
98
 
95
- assert_equal $smtp.outbox.size, 1
99
+ assert $smtp.outbox.pop
100
+ end
101
+
102
+ test "block behavior" do |notifier|
103
+ notifier.behaviors = [:deliver]
104
+
105
+ notifier.run do
106
+ raise ArgumentError, "A bad argument"
107
+ end
108
+
109
+ assert $smtp.outbox.pop
96
110
  end
97
111
 
98
- $smtp.stop
99
- $smtp.join
112
+ test "block with environment" do |notifier|
113
+ notifier.behaviors = [:deliver]
114
+
115
+ notifier.run("Foo" => "Bar") do
116
+ raise ArgumentError, "A bad argument"
117
+ end
118
+
119
+ headers, body = parse_email($smtp.outbox.pop[:data])
120
+
121
+ assert body.include?("Foo: Bar")
122
+ end
data/test/middleware.rb CHANGED
@@ -26,6 +26,7 @@ test "extracts interesting stuff from the request" do |app|
26
26
  "HTTP_USER_AGENT" => "Mozilla/4.0 (compatible)",
27
27
  "HTTP_REFERER" => "/other",
28
28
  "HTTP_COOKIE" => "foo=bar",
29
+ "REMOTE_ADDR" => "127.0.0.2",
29
30
  )
30
31
 
31
32
  begin
@@ -33,13 +34,53 @@ test "extracts interesting stuff from the request" do |app|
33
34
  rescue ZeroDivisionError
34
35
  end
35
36
 
36
- headers, body = parse_email($smtp.outbox.last[:data])
37
+ headers, body = parse_email($smtp.outbox.pop[:data])
37
38
 
38
39
  assert_equal headers["Subject"], "ZeroDivisionError: divided by 0"
39
- assert body.include?("GET http://example.org/baz")
40
+ assert body.include?("GET http://example.org/baz\r\n")
40
41
  assert body.include?("User-Agent: Mozilla/4.0 (compatible)")
41
42
  assert body.include?("Referrer: /other")
42
43
  assert body.include?("Cookie: foo=bar")
44
+ assert body.include?("IP: 127.0.0.2")
45
+ end
46
+
47
+ test "extracts the posted form" do |app|
48
+ env = Rack::MockRequest.env_for(
49
+ "/baz",
50
+ "REQUEST_METHOD" => "POST",
51
+ input: "foo=bar&baz=qux",
52
+ )
53
+
54
+ begin
55
+ app.call(env)
56
+ rescue ZeroDivisionError
57
+ end
58
+
59
+ headers, body = parse_email($smtp.outbox.pop[:data])
60
+
61
+ assert_equal headers["Subject"], "ZeroDivisionError: divided by 0"
62
+ assert body.include?("POST http://example.org/baz\r\n")
63
+ assert body.include?(%Q[ {"foo"=>"bar", "baz"=>"qux"}])
64
+ end
65
+
66
+ test "extracts the request body" do |app|
67
+ env = Rack::MockRequest.env_for(
68
+ "/baz",
69
+ "REQUEST_METHOD" => "POST",
70
+ "CONTENT_TYPE" => "text/plain; charset=utf-8",
71
+ input: "foo:bar",
72
+ )
73
+
74
+ begin
75
+ app.call(env)
76
+ rescue ZeroDivisionError
77
+ end
78
+
79
+ headers, body = parse_email($smtp.outbox.pop[:data])
80
+
81
+ assert_equal headers["Subject"], "ZeroDivisionError: divided by 0"
82
+ assert body.include?("POST http://example.org/baz\r\n")
83
+ assert body.include?(%Q[ foo:bar])
43
84
  end
44
85
 
45
86
  test "doesn't raise when the notification fails" do |app|
data/test/prelude.rb CHANGED
@@ -4,16 +4,57 @@ require "mini-smtp-server"
4
4
  require_relative "../lib/exception_no"
5
5
 
6
6
  class SMTPServer < MiniSmtpServer
7
- def outbox
8
- @outbox ||= []
7
+ attr :outbox
8
+
9
+ def initialize(*args)
10
+ @outbox = QueueWithTimeout.new
11
+ super(*args)
9
12
  end
10
13
 
11
14
  def new_message_event(message)
12
- outbox << message
15
+ @outbox << message
13
16
  true
14
17
  end
15
18
  end
16
19
 
20
+ # Source: http://spin.atomicobject.com/2014/07/07/ruby-queue-pop-timeout
21
+ class QueueWithTimeout
22
+ Timeout = Class.new(StandardError)
23
+
24
+ def initialize
25
+ @mutex = Mutex.new
26
+ @queue = []
27
+ @recieved = ConditionVariable.new
28
+ end
29
+
30
+ def <<(x)
31
+ @mutex.synchronize do
32
+ @queue << x
33
+ @recieved.signal
34
+ end
35
+ end
36
+
37
+ def size
38
+ @queue.size
39
+ end
40
+
41
+ def clear
42
+ @mutex.synchronize do
43
+ @queue.clear
44
+ end
45
+ end
46
+
47
+ def pop(timeout = 2)
48
+ @mutex.synchronize do
49
+ if @queue.empty?
50
+ @recieved.wait(@mutex, timeout) if timeout != 0
51
+ raise Timeout, "queue empty" if @queue.empty?
52
+ end
53
+ @queue.pop
54
+ end
55
+ end
56
+ end
57
+
17
58
  def parse_email(raw)
18
59
  headers = {}
19
60
  body = []
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exception_no
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Educabilia
@@ -9,8 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-28 00:00:00.000000000 Z
12
+ date: 2014-09-10 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: cutest
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ! '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: mini-smtp-server
16
30
  requirement: !ruby/object:Gem::Requirement
@@ -26,7 +40,7 @@ dependencies:
26
40
  - !ruby/object:Gem::Version
27
41
  version: '0'
28
42
  - !ruby/object:Gem::Dependency
29
- name: cutest
43
+ name: rack
30
44
  requirement: !ruby/object:Gem::Requirement
31
45
  requirements:
32
46
  - - ! '>='