nested_exceptions 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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