exception_mailer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a946a173c95b3e0838cf08501f8718a9169d981d
4
+ data.tar.gz: 7b95885a16e8d102855cbbfe272cfb1b76b30b08
5
+ SHA512:
6
+ metadata.gz: 7030cd4c58cc19749824fca4dd7148af7b16b2e3e613eb60dbd35f1ad9710b6b4be2b6833853029da48910606c91b4b7a841808f549fc36286742674e97f551e
7
+ data.tar.gz: 23c79a72ba78511e96bdc3fd48b4d51dd4b88923174aa3750377386bb6ffa5925baadc7381cb63f6044de75cfae59ac76f647fa1c315caaf590558731da0b5e2
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sc.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Tyler Hartland
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # Exception Mailer
2
+
3
+ Send an email in response to uncaught exceptions
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'exception_mailer'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install exception_mailer
18
+
19
+ ## Usage
20
+ Uses http://www.ruby-doc.org/stdlib-2.1.1/libdoc/net/smtp/rdoc/Net/SMTP.html
21
+ ```
22
+ ExceptionMailer.mail_exceptions do
23
+ # code that may raise an exception
24
+ end
25
+ ```
26
+ ```
27
+ include ExceptionMailer
28
+
29
+ mail_exceptions do
30
+ # code that may raise an exception
31
+ end
32
+ ```
33
+ Oops, don't forget config!
34
+ ```
35
+ ExceptionMailer.configure do |c|
36
+ c.server = 'your.smtp.server' # defaults to 'localhost'
37
+ c.port = 25 # defaults to this value
38
+ c.host = 'your.hostname'
39
+ c.account = 'your@smtp.account'
40
+ c.password = ENV['SMTP_PASSWORD'] # or load it from a file -- hardcoded passwords are bad, mmkay?
41
+ c.auth_method = :plain # or :login or :cram_md5
42
+
43
+ c.from = 'from' # defaults to 'ExceptionMailer'
44
+ c.to = [ 'one@destination.address', 'another@to.address' ] # or a single string
45
+ c.subject = 'your subject line' # defaults to 'Exception Occurred'
46
+ end
47
+ ```
48
+ All of the above options can be overridden for a specific block
49
+ ```
50
+ mail_exceptions(to: 'mom@msn.net', subject: 'Hi Mom!') do
51
+ # code that raises exceptions your mom wants to see
52
+ end
53
+ ```
54
+ The message body will look kind of like this:
55
+ ```
56
+ RuntimeError: hi
57
+ (irb):6:in `block in irb_binding'
58
+ /Users/tyler.hartland/dev/exception_mailer/lib/exception_mailer.rb:12:in `mail_exceptions'
59
+ (irb):6:in `irb_binding'
60
+ /Users/tyler.hartland/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/irb/workspace.rb:86:in `eval'
61
+ ...
62
+ ```
63
+
64
+ ## Contributing
65
+
66
+ 1. Fork it ( http://github.com/<my-github-username>/exception_mailer/fork )
67
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
68
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
69
+ 4. Push to the branch (`git push origin my-new-feature`)
70
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "exception_mailer"
7
+ spec.version = `cat version`.chomp
8
+ spec.authors = ["Tyler Hartland"]
9
+ spec.email = ["tylerhartland7@gmail.com"]
10
+ spec.summary = 'Simple email notification of uncaught exceptions'
11
+ spec.homepage = ""
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.5"
20
+ spec.add_development_dependency "rake"
21
+ spec.add_development_dependency "rspec"
22
+ end
@@ -0,0 +1,27 @@
1
+ require 'exception_mailer/mailer'
2
+
3
+ module ExceptionMailer
4
+ class << self
5
+ attr_accessor :host, :server, :port, :account, :password, :to, :from, :subject, :auth_method
6
+
7
+ def configure
8
+ yield self
9
+ end
10
+
11
+ def mail_exceptions(opts={})
12
+ yield
13
+ rescue Exception => e
14
+ Mailer.new(opts).send_notification(e)
15
+ raise e
16
+ end
17
+ end
18
+
19
+ self.server = 'localhost'
20
+ self.port = 25
21
+ self.from = 'ExceptionMailer'
22
+ self.subject = 'Exception Occurred'
23
+
24
+ def mail_exceptions(opts={}, &block)
25
+ ExceptionMailer.mail_exceptions(opts, &block)
26
+ end
27
+ end
@@ -0,0 +1,63 @@
1
+ require 'net/smtp'
2
+
3
+ module ExceptionMailer
4
+ class Mailer
5
+ attr_reader :host, :server, :port, :account, :password, :to, :from, :subject
6
+
7
+ def initialize(opts)
8
+ @host = opts[:host] || ExceptionMailer.host
9
+ @server = opts[:server] || ExceptionMailer.server
10
+ @port = opts[:port] || ExceptionMailer.port
11
+ @account = opts[:account] || ExceptionMailer.account
12
+ @password = opts[:password] || ExceptionMailer.password
13
+ @auth_method = opts[:auth_method] || ExceptionMailer.auth_method
14
+ @to = opts[:to] || ExceptionMailer.to
15
+ @from = opts[:from] || ExceptionMailer.from
16
+ @subject = opts[:subject] || ExceptionMailer.subject
17
+
18
+ @to = [ @to ] unless @to.kind_of? Array
19
+ end
20
+
21
+ def send_notification(exception)
22
+ Net::SMTP.start(*start_args) do |smtp|
23
+ smtp.send_message(build_msg(exception), from, *to)
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def start_args
30
+ [ :server, :port, :host, :account, :password, :auth_method ].inject([]) do |args, arg|
31
+ return args if send(arg).nil?
32
+ args << send(arg)
33
+ end
34
+ end
35
+
36
+ def build_msg(exception)
37
+ <<-END_OF_MESSAGE
38
+ From: <#{from}>
39
+ #{to.map { |t| "To: <#{t}>" }.join("\n") }
40
+ Subject: #{subject}
41
+ Date: #{now}
42
+ Message-Id: <#{msg_id}>
43
+
44
+ #{body(exception)}
45
+ END_OF_MESSAGE
46
+ end
47
+
48
+ def body(exception)
49
+ [
50
+ "#{exception.class}: #{exception.message}",
51
+ "#{exception.backtrace.join("\n")}"
52
+ ].join("\n")
53
+ end
54
+
55
+ def msg_id
56
+ rand(1_000_000_000)
57
+ end
58
+
59
+ def now
60
+ Time.now
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require 'exception_mailer/mailer'
3
+ include ExceptionMailer
4
+
5
+ describe Mailer do
6
+ let(:mailer) { Mailer.new(
7
+ host: 'test host',
8
+ server: 'test server',
9
+ port: 'test port',
10
+ to: 'test to',
11
+ from: 'test from',
12
+ subject: 'test subject'
13
+ )
14
+ }
15
+
16
+ describe '#send_notification' do
17
+ let(:exception) { Exception.new 'a test exception' }
18
+ let(:smtp) { double(send_message: nil) }
19
+ let(:expected_host) { 'test host' }
20
+ let(:expected_server) { 'test server' }
21
+ let(:expected_port) { 'test port' }
22
+ let(:expected_message) { "From: <test from>\nTo: <test to>\nSubject: test subject\nDate: 2014-04-29 12:44:59 -0500\nMessage-Id: <1>\n\nException: a test exception\ntest\nbacktrace\n" }
23
+ let(:expected_from) { 'test from' }
24
+ let(:expected_to) { 'test to' }
25
+
26
+ before do
27
+ exception.set_backtrace([ 'test', 'backtrace' ])
28
+ mailer.stub(:now).and_return(Time.new(2014, 4, 29, 12, 44, 59, '-05:00'))
29
+ mailer.stub(:msg_id).and_return(1)
30
+ end
31
+
32
+ it 'passes server and port to Net::SMTP.start' do
33
+ expect(Net::SMTP).to receive(:start).with(expected_server, expected_port, expected_host)
34
+ mailer.send_notification(exception)
35
+ end
36
+
37
+ it 'builds the expected message' do
38
+ expect(Net::SMTP).to receive(:start).and_yield(smtp)
39
+ expect(smtp).to receive(:send_message) do |msg, from, to|
40
+ expect(msg).to eq expected_message
41
+ expect(from).to eq expected_from
42
+ expect(to).to eq expected_to
43
+ end
44
+ mailer.send_notification(exception)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'exception_mailer'
3
+
4
+ describe ExceptionMailer do
5
+ describe '.mail_exceptions' do
6
+ let(:exception) { Exception.new 'a test exception' }
7
+ let(:mailer) { double(send_notification: nil) }
8
+ it 'rescues exceptions and passes them to ExceptionMailer::Mailer' do
9
+ expect(ExceptionMailer::Mailer).to receive(:new).and_return(mailer)
10
+ expect(mailer).to receive(:send_notification).with(exception)
11
+ expect {
12
+ ExceptionMailer.mail_exceptions { raise exception }
13
+ }.to raise_error exception
14
+ end
15
+ end
16
+
17
+ describe '#mail_exceptions' do
18
+ before do
19
+ class ExceptionMailerIncluder
20
+ include ExceptionMailer
21
+ end
22
+ end
23
+
24
+ let(:opts) { double }
25
+ let(:block) { Proc.new {} }
26
+
27
+ it 'passes opts and block to ExceptionMailer.mail_exceptions' do
28
+ expect(ExceptionMailer).to receive(:mail_exceptions).with(opts, &block)
29
+ ExceptionMailerIncluder.new.mail_exceptions(opts, &block)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,17 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end
data/version ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: exception_mailer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tyler Hartland
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - tylerhartland7@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - exception_mailer.gemspec
69
+ - lib/exception_mailer.rb
70
+ - lib/exception_mailer/mailer.rb
71
+ - spec/lib/exception_mailer/mailer_spec.rb
72
+ - spec/lib/exception_mailer_spec.rb
73
+ - spec/spec_helper.rb
74
+ - version
75
+ homepage: ''
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.1.11
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Simple email notification of uncaught exceptions
99
+ test_files:
100
+ - spec/lib/exception_mailer/mailer_spec.rb
101
+ - spec/lib/exception_mailer_spec.rb
102
+ - spec/spec_helper.rb
103
+ has_rdoc: