merb-exceptions 0.9.9 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- merb_exceptions
1
+ merb-exceptions
2
2
  ===============
3
3
  A simple Merb plugin to ease exception notifications.
4
4
 
@@ -6,14 +6,14 @@ The notifier currently supports two interfaces, Email Alerts and Web Hooks. Emai
6
6
 
7
7
  Getting Going
8
8
  -------------
9
- Once you have the Gem installed you will need to add it as a dependency in your projects `init.rb` file
9
+ Once you have the Gem installed you will need to add it as a dependency in your projects `dependencies.rb` file
10
10
 
11
- dependency 'merb_exceptions'
11
+ dependency 'merb-exceptions'
12
12
 
13
- Configuration goes in 'config/init.rb' file in 'Merb::BootLoader.before_app_loads'. See 'Settings' below for a full description of the options.
13
+ Configuration goes in your projects `config/init.rb` file inside `Merb::BootLoader.before_app_loads`. See the 'Settings' section below for a full description of the options.
14
14
 
15
15
  Merb::Plugins.config[:exceptions] = {
16
- :web_hooks => ['http://localhost:4000/exceptions'],
16
+ :web_hooks => ['http://example.com'],
17
17
  :email_addresses => ['hello@exceptions.com', 'user@myapp.com'],
18
18
  :app_name => "My App Name",
19
19
  :email_from => "exceptions@myapp.com",
@@ -42,17 +42,17 @@ Settings
42
42
 
43
43
  Advanced usage
44
44
  --------------
45
- Including `MerbExceptions::ControllerExtensions` creates an `internal_server_error` action which renders the default exception page and delivers the exception. If you need to rescue any other exceptions or customize the behavior in any way you can write your own actions in `ExceptionsController` and make a call to `render_and_notify`.
45
+ merb-exceptions will deliver exceptions for any unhandled exceptions (exceptions that do not have views defined in the `Exceptions` controller)
46
46
 
47
- For example to be notified of 404's:
47
+ You can cause handled exceptions to send notifications as well, for example to be notified of 404's:
48
+
49
+ after :notify_of_exceptions, :only => :not_found
48
50
 
49
51
  def not_found
50
52
  render_and_notify :format => :html
51
53
  end
52
54
 
53
- `render_and_notify` - passes any provided options directly to Merb's render method and then sends the notification after rendering.
54
-
55
- `notify_of_exceptions` - if you need to handle the render yourself for some reason then you can call this method directly. It sends notifications without any rendering logic. Note though that if you are sending lots of notifications this could delay sending a response back to the user so try to avoid using it where possible.
55
+ `notify_of_exceptions` - sends notifications without any rendering logic. Note though that if you are sending lots of notifications this could delay sending a response back to the user so it is better to use after rendering.
56
56
 
57
57
  Web hooks
58
58
  ---------
data/Rakefile CHANGED
@@ -20,7 +20,7 @@ GEM_EMAIL = "andy@new-bamboo.co.uk"
20
20
 
21
21
  GEM_NAME = "merb-exceptions"
22
22
  PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
23
- GEM_VERSION = (Merb::VERSION rescue "0.9.9") + PKG_BUILD
23
+ GEM_VERSION = Merb::VERSION + PKG_BUILD
24
24
 
25
25
  RELEASE_NAME = "REL #{GEM_VERSION}"
26
26
 
@@ -35,7 +35,7 @@ spec = Gem::Specification.new do |s|
35
35
  s.author = GEM_AUTHOR
36
36
  s.email = GEM_EMAIL
37
37
  s.homepage = PROJECT_URL
38
- s.add_dependency('merb-core', '>= 0.9.9')
38
+ s.add_dependency('merb-core', ">= #{Merb::VERSION}")
39
39
  s.require_path = 'lib'
40
40
  s.files = %w(LICENSE README.markdown Rakefile) + Dir.glob("{lib,spec}/**/*")
41
41
  end
@@ -55,7 +55,7 @@ task :uninstall do
55
55
  end
56
56
 
57
57
  desc "Run all specs"
58
- Spec::Rake::SpecTask.new("specs") do |t|
58
+ Spec::Rake::SpecTask.new("spec") do |t|
59
59
  t.spec_opts = ["--format", "specdoc", "--colour"]
60
60
  t.spec_files = Dir["spec/**/*_spec.rb"].sort
61
61
  end
@@ -17,13 +17,14 @@ if defined?(Merb::Plugins)
17
17
  Merb::BootLoader.after_app_loads do
18
18
  if Object.const_defined?(:Exceptions)
19
19
  Exceptions.send(:include, MerbExceptions::ExceptionsHelper)
20
- if Merb::Plugins.config[:exceptions][:environments].include?(Merb.env)
21
- Exceptions.send(:include, MerbExceptions::ControllerExtensions)
22
- end
20
+ end
21
+ if Merb::Plugins.config[:exceptions][:environments].include?(Merb.env)
22
+ Merb::Dispatcher::DefaultException.send(:include, MerbExceptions::ExceptionsHelper)
23
+ Merb::Dispatcher::DefaultException.send(:include, MerbExceptions::DefaultExceptionExtensions)
23
24
  end
24
25
  end
25
26
 
26
27
  require 'merb-exceptions/notification'
27
- require 'merb-exceptions/controller_extensions'
28
- require 'merb-exceptions/exceptions_helper.rb'
28
+ require 'merb-exceptions/default_exception_extensions'
29
+ require 'merb-exceptions/exceptions_helper'
29
30
  end
@@ -0,0 +1,9 @@
1
+ module MerbExceptions
2
+ module DefaultExceptionExtensions
3
+ def self.included(mod)
4
+ mod.class_eval do
5
+ after :notify_of_exceptions
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,16 +1,32 @@
1
1
  module MerbExceptions
2
2
  module ExceptionsHelper
3
3
  protected
4
-
5
- # renders unless Merb::Plugins.config[:exceptions][:environments]
6
- # includes the current environment, in which case it passes any
7
- # provided options directly to Merb's render method and then
8
- # sends the notification after rendering.
9
- def render_and_notify(*opts)
4
+ # if you need to handle the render yourself for some reason, you can call
5
+ # this method directly. It sends notifications without any rendering logic.
6
+ # Note though that if you are sending lots of notifications this could
7
+ # delay sending a response back to the user so try to avoid using it
8
+ # where possible.
9
+ def notify_of_exceptions
10
10
  if Merb::Plugins.config[:exceptions][:environments].include?(Merb.env)
11
- self.render_then_call(self.render(*opts)) { notify_of_exceptions }
12
- else
13
- self.render(*opts)
11
+ begin
12
+ request = self.request
13
+
14
+ details = {}
15
+ details['exceptions'] = request.exceptions
16
+ details['params'] = params
17
+ details['environment'] = request.env.merge( 'process' => $$ )
18
+ details['url'] = "#{request.protocol}#{request.env["HTTP_HOST"]}#{request.uri}"
19
+ MerbExceptions::Notification.new(details).deliver!
20
+ rescue Exception => e
21
+ exceptions = request.exceptions << e
22
+ Merb.logger.fatal!("Exception Notification Failed:\n" + (exceptions).inspect)
23
+ File.open(Merb.root / 'log' / 'notification_errors.log', 'a') do |log|
24
+ log.puts("Exception Notification Failed:")
25
+ exceptions.each do |e|
26
+ log.puts(Merb.exception(e))
27
+ end
28
+ end
29
+ end
14
30
  end
15
31
  end
16
32
 
@@ -0,0 +1,16 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe MerbExceptions::DefaultExceptionExtensions do
4
+
5
+ before(:each) do
6
+ Merb::Router.prepare do
7
+ default_routes
8
+ end
9
+ end
10
+
11
+ it "should notify_of_exceptions" do
12
+ MerbExceptions::Notification.should_receive(:new)
13
+ request("/raise_error/index")
14
+ end
15
+
16
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe MerbExceptions::DefaultExceptionExtensions do
4
+
5
+ before(:each) do
6
+ Merb::Router.prepare do
7
+ default_routes
8
+ end
9
+ end
10
+
11
+ it "should notify_of_exceptions" do
12
+ MerbExceptions::Notification.should_receive(:new)
13
+ request("/not_found/index")
14
+ end
15
+
16
+ it "should log fatal on failure" do
17
+ MerbExceptions::Notification.should_receive(:new).and_raise(StandardError)
18
+ with_level(:fatal) do
19
+ request("/not_found/index")
20
+ end.should include_log("Exception Notification Failed:")
21
+ end
22
+
23
+ end
@@ -2,14 +2,82 @@ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
2
  require "rubygems"
3
3
  require "merb-core"
4
4
  require "spec"
5
- require "merb_exceptions"
5
+ require "merb-exceptions"
6
6
 
7
- # merb-exceptions needs to include itself into this class
8
- class Exceptions < Merb::Controller; end
7
+ class Application < Merb::Controller
8
+ end
9
+
10
+ class RaiseError < Application
11
+ def index
12
+ raise StandardError, 'Something went wrong'
13
+ end
14
+ end
15
+
16
+ class NotFound < Application
17
+ end
18
+
19
+ class Exceptions < Application
20
+ after :notify_of_exceptions, :only => :not_found
21
+
22
+ def not_found
23
+ render '404 not found'
24
+ end
25
+ end
9
26
 
10
27
  Merb::Plugins.config[:exceptions][:environments] = 'test'
11
28
  Merb.start :environment => 'test'
12
29
 
30
+ module Merb
31
+ module Test
32
+ module RspecMatchers
33
+ class IncludeLog
34
+ def initialize(expected)
35
+ @expected = expected
36
+ end
37
+
38
+ def matches?(target)
39
+ target.rewind
40
+ @text = target.read
41
+ @text =~ (String === @expected ? /#{Regexp.escape @expected}/ : @expected)
42
+ end
43
+
44
+ def failure_message
45
+ "expected to find `#{@expected}' in the log but got:\n" <<
46
+ @text.map {|s| " #{s}" }.join
47
+ end
48
+
49
+ def negative_failure_message
50
+ "exected not to find `#{@expected}' in the log but got:\n" <<
51
+ @text.map {|s| " #{s}" }.join
52
+ end
53
+
54
+ def description
55
+ "include #{@text} in the log"
56
+ end
57
+ end
58
+
59
+ def include_log(expected)
60
+ IncludeLog.new(expected)
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ Spec::Runner.configure do |config|
67
+ config.include Merb::Test::ControllerHelper
68
+ config.include Merb::Test::RequestHelper
69
+ config.include Merb::Test::RouteHelper
70
+ config.include Merb::Test::RspecMatchers
71
+
72
+ def with_level(level)
73
+ Merb::Config[:log_stream] = StringIO.new
74
+ Merb::Config[:log_level] = level
75
+ Merb.reset_logger!
76
+ yield
77
+ Merb::Config[:log_stream]
78
+ end
79
+ end
80
+
13
81
  module NotificationSpecHelper
14
82
  def mock_details(opts={})
15
83
  {
@@ -19,7 +87,7 @@ module NotificationSpecHelper
19
87
  'url' => 'http://www.my-app.com/errors/1'
20
88
  }.merge(opts)
21
89
  end
22
-
90
+
23
91
  def mock_merb_config(opts={})
24
92
  Merb::Plugins.config[:exceptions].merge!(opts)
25
93
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: merb-exceptions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.9
4
+ version: 0.9.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Kent
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-10-13 00:00:00 -07:00
12
+ date: 2008-10-21 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.9.9
23
+ version: 0.9.10
24
24
  version:
25
25
  description: Email and web hook exceptions for Merb.
26
26
  email: andy@new-bamboo.co.uk
@@ -36,12 +36,14 @@ files:
36
36
  - README.markdown
37
37
  - Rakefile
38
38
  - lib/merb-exceptions
39
- - lib/merb-exceptions/controller_extensions.rb
39
+ - lib/merb-exceptions/default_exception_extensions.rb
40
40
  - lib/merb-exceptions/exceptions_helper.rb
41
41
  - lib/merb-exceptions/notification.rb
42
42
  - lib/merb-exceptions/templates
43
43
  - lib/merb-exceptions/templates/email.erb
44
44
  - lib/merb-exceptions.rb
45
+ - spec/default_exception_extensions_spec.rb
46
+ - spec/exceptions_helper_spec.rb
45
47
  - spec/notification_spec.rb
46
48
  - spec/spec_helper.rb
47
49
  has_rdoc: true
@@ -66,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
68
  requirements: []
67
69
 
68
70
  rubyforge_project:
69
- rubygems_version: 1.2.0
71
+ rubygems_version: 1.3.0
70
72
  signing_key:
71
73
  specification_version: 2
72
74
  summary: Email and web hook exceptions for Merb.
@@ -1,43 +0,0 @@
1
- module MerbExceptions
2
- module ControllerExtensions
3
-
4
- def self.included(mod)
5
- mod.class_eval do
6
- def base
7
- self.render_and_notify template_or_message, :layout=>false
8
- end
9
-
10
- def exception
11
- self.render_and_notify template_or_message, :layout=>false
12
- end
13
-
14
- private
15
-
16
- def template_or_message
17
- if File.exists?(Merb.root / 'app' / 'views' / 'exceptions' / 'internal_server_error.html.erb')
18
- :internal_server_error
19
- else
20
- '500 exception. Please customize this page by creating app/views/exceptions/internal_server_error.html.erb.'
21
- end
22
- end
23
- end
24
- end
25
-
26
- # if you need to handle the render yourself for some reason, you can call
27
- # this method directly. It sends notifications without any rendering logic.
28
- # Note though that if you are sending lots of notifications this could
29
- # delay sending a response back to the user so try to avoid using it
30
- # where possible.
31
- def notify_of_exceptions
32
- request = self.request
33
-
34
- details = {}
35
- details['exceptions'] = request.exceptions
36
- details['params'] = params
37
- details['environment'] = request.env.merge( 'process' => $$ )
38
- details['url'] = "#{request.protocol}#{request.env["HTTP_HOST"]}#{request.uri}"
39
- MerbExceptions::Notification.new(details).deliver!
40
- end
41
-
42
- end
43
- end