nested_exceptions 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ bin
6
+ .rbx
data/.rspec ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in nested_exceptions.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec) do |spec|
6
+ spec.pattern = FileList['spec/**/*_spec.rb']
7
+ end
8
+
9
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
10
+ spec.pattern = 'spec/**/*_spec.rb'
11
+ spec.ruby_opts = '--debug'
12
+ spec.skip_bundler = true
13
+ spec.rcov = true
14
+ spec.rcov_opts = %w{--exclude generator_internal,jsignal_internal,gems\/,spec\/}
15
+ end
16
+
17
+ task :default => :spec
@@ -0,0 +1,23 @@
1
+ module NestedExceptions
2
+ class << self
3
+ # Define a set of standard exception classes as recommended in
4
+ # http://exceptionalruby.com/
5
+ #
6
+ # I actually recommend that you just define these manually, but this may be
7
+ # a handy shortcut in smaller projects.
8
+ def define_standard_exception_classes_in(target_module)
9
+ definitions = %{
10
+ class Error < StandardError; include NestedExceptions; end
11
+ class UserError < Error; end
12
+ class LogicError < Error; end
13
+ class ClientError < LogicError; end
14
+ class InternalError < LogicError; end
15
+ class TransientError < Error; end
16
+ }
17
+ target_module.module_eval definitions
18
+ [:Error, :UserError, :LogicError, :ClientError, :InternalError, :TransientError].map do |name|
19
+ target_module.const_get name
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ require 'nested_exceptions'
2
+
3
+ NestedExceptions::GLOBAL = true
4
+
5
+ [NoMemoryError, ScriptError, SignalException, StandardError, SystemExit].each do |klass|
6
+ klass.send :include, NestedExceptions
7
+ end
@@ -0,0 +1,11 @@
1
+ module NestedExceptions
2
+ VERSION = "1.0.0"
3
+
4
+ def self.const_missing(name)
5
+ if name == 'GLOBAL' or name == :GLOBAL
6
+ NestedExceptions.const_set(name, false)
7
+ else
8
+ super
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,50 @@
1
+ require "nested_exceptions/version"
2
+ require "nested_exceptions/define"
3
+
4
+ # Just include this module in your custom exception class
5
+ module NestedExceptions
6
+ attr_reader :cause
7
+
8
+ def initialize(message = nil, cause = nil)
9
+ @cause = cause || $!
10
+ super(message)
11
+ end
12
+
13
+ if Object.const_defined? :RUBY_ENGINE and RUBY_ENGINE == 'jruby' or RUBY_ENGINE == 'rbx'
14
+ def backtrace
15
+ return @processed_backtrace if defined? @processed_backtrace and @processed_backtrace
16
+ @processed_backtrace = process_backtrace(super)
17
+ end
18
+ else
19
+ def set_backtrace(bt)
20
+ super process_backtrace(bt)
21
+ end
22
+ end
23
+
24
+ def root_cause
25
+ rc = e = self
26
+ while e
27
+ rc = e
28
+ break unless e.respond_to? :cause
29
+ e = e.cause
30
+ end
31
+ rc
32
+ end
33
+
34
+ protected
35
+
36
+ def process_backtrace(bt)
37
+ if cause
38
+ cause.backtrace.reverse.each do |line|
39
+ if bt.last == line
40
+ bt.pop
41
+ else
42
+ break
43
+ end
44
+ end
45
+ bt << "--- cause: #{cause.class.name}: #{cause}"
46
+ bt.concat cause.backtrace
47
+ end
48
+ bt
49
+ end
50
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "nested_exceptions/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "nested_exceptions"
7
+ s.version = NestedExceptions::VERSION
8
+ s.authors = ["Darrick Wiebe"]
9
+ s.email = ["dw@xnlogic.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Support nested exceptions in all rubies}
12
+ s.description = %q{Based on ideas in http://exceptionalruby.com/ and the nestegg gem which does not support JRuby.}
13
+
14
+ s.rubyforge_project = "nested_exceptions"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_development_dependency "rspec"
21
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ module ErrorSpec
4
+
5
+ NestedExceptions.define_standard_exception_classes_in ErrorSpec
6
+
7
+ class Example
8
+ def bug
9
+ raise 'bug'
10
+ end
11
+
12
+ def nested_bug
13
+ bug
14
+ end
15
+
16
+ def problem
17
+ nested_bug
18
+ rescue
19
+ raise InternalError, 'problem'
20
+ end
21
+
22
+ def nested_problem
23
+ problem
24
+ end
25
+
26
+ def double_bug
27
+ nested_problem
28
+ rescue
29
+ raise 'oops'
30
+ end
31
+ end
32
+ end
33
+
34
+ describe NestedExceptions do
35
+ let(:ex) { ErrorSpec::Example.new }
36
+ def in_rescue
37
+ if Object.const_defined? :RUBY_ENGINE and RUBY_ENGINE == 'jruby'
38
+ ''
39
+ elsif RUBY_VERSION =~ /^1\.[0-8]\./
40
+ ''
41
+ else
42
+ in_rescue = 'rescue in '
43
+ end
44
+ end
45
+
46
+ it 'should create a stack trace correctly' do
47
+ stack = raise rescue $!.backtrace
48
+ stack.first.should =~ /#{__FILE__}:#{__LINE__ - 1}/
49
+ end
50
+
51
+ describe 'normal StandardError' do
52
+ subject do
53
+ @stack = raise rescue $!.backtrace; ex.bug rescue $!
54
+ end
55
+ its(:message) { should == 'bug' }
56
+ its(:backtrace) { should == ["#{__FILE__}:9:in `bug'"] + @stack }
57
+ end
58
+
59
+ describe 'nested InternalError' do
60
+ subject do
61
+ @stack = raise rescue $!.backtrace; ex.problem rescue $!
62
+ end
63
+ its(:message) { should == 'problem' }
64
+ its('root_cause.message') { should == 'bug' }
65
+ its(:backtrace) do
66
+ should == [
67
+ "#{__FILE__}:19:in `#{in_rescue}problem'",
68
+ "--- cause: RuntimeError: bug",
69
+ "#{__FILE__}:9:in `bug'",
70
+ "#{__FILE__}:13:in `nested_bug'",
71
+ "#{__FILE__}:17:in `problem'"
72
+ ] + @stack
73
+ end
74
+ end
75
+
76
+ describe 'double nested StandardError' do
77
+ subject do
78
+ @stack = raise rescue $!.backtrace; ex.double_bug rescue $!
79
+ end
80
+ its(:message) { should == 'oops' }
81
+ its('root_cause.message') { should == 'bug' }
82
+ its(:backtrace) do
83
+ should == [
84
+ "#{__FILE__}:29:in `#{in_rescue}double_bug'",
85
+ "--- cause: ErrorSpec::InternalError: problem",
86
+ "#{__FILE__}:19:in `#{in_rescue}problem'",
87
+ "--- cause: RuntimeError: bug",
88
+ "#{__FILE__}:9:in `bug'",
89
+ "#{__FILE__}:13:in `nested_bug'",
90
+ "#{__FILE__}:17:in `problem'",
91
+ "#{__FILE__}:23:in `nested_problem'",
92
+ "#{__FILE__}:27:in `double_bug'"
93
+ ] + @stack
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,2 @@
1
+ require 'rspec'
2
+ require 'nested_exceptions/global'
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nested_exceptions
3
+ version: !ruby/object:Gem::Version
4
+ hash: 2387456872237229630
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Darrick Wiebe
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-09-21 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 2002549777813010636
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: Based on ideas in http://exceptionalruby.com/ and the nestegg gem which does not support JRuby.
36
+ email:
37
+ - dw@xnlogic.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - .gitignore
46
+ - .rspec
47
+ - Gemfile
48
+ - Rakefile
49
+ - lib/nested_exceptions.rb
50
+ - lib/nested_exceptions/define.rb
51
+ - lib/nested_exceptions/global.rb
52
+ - lib/nested_exceptions/version.rb
53
+ - nested_exceptions.gemspec
54
+ - spec/nested_exceptions_spec.rb
55
+ - spec/spec_helper.rb
56
+ has_rdoc: true
57
+ homepage: ""
58
+ licenses: []
59
+
60
+ post_install_message:
61
+ rdoc_options: []
62
+
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 2002549777813010636
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 2002549777813010636
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project: nested_exceptions
86
+ rubygems_version: 1.5.2
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Support nested exceptions in all rubies
90
+ test_files:
91
+ - spec/nested_exceptions_spec.rb
92
+ - spec/spec_helper.rb