readable_exceptions 0.0.1

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,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in readable_exceptions.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Overview
2
+
3
+ Given a configured exception type and error context, returns a human readable error message.
4
+
5
+ # Configure it
6
+
7
+ Create your configuration file, readable_exceptions.yml.
8
+
9
+ "WallPostException":
10
+ wall_context: "We can not post to your wall"
11
+ friend_wall_context: "We can not post to your friends wall"
12
+
13
+ "WallPostException::IntermittentError":
14
+ wall_context: "We can not post to your wall right now. We'll try again later."
15
+
16
+ WallPostException::IntermittentError is a child class of WallPostException.
17
+
18
+ # Use it
19
+
20
+ ReadableExceptions.setup(File.dirname(__FILE__) + "/readable_exceptions.yml")
21
+
22
+ begin
23
+ post_to_wall()
24
+ rescue WallPostException => e
25
+ puts e.readable_message(:wall_context) # puts "We can not post to your wall"
26
+ end
27
+
28
+ begin
29
+ post_to_friends_wall()
30
+ rescue WallPostException => e
31
+ puts e.readable_message(:friend_wall_context) # puts "We can not post to your friends wall"
32
+ end
33
+
34
+ begin
35
+ post_to_wall()
36
+ rescue WallPostException::IntermittentError => e
37
+ puts e.readable_message(:wall_context) # puts "We can not post to your wall right now. We'll try again later."
38
+ end
39
+
40
+ begin
41
+ post_to_friends_wall()
42
+ rescue WallPostException::IntermittentError => e
43
+ puts e.readable_message(:friend_wall_context) # puts "We can not post to your friends wall"
44
+ end
45
+
46
+ begin
47
+ raise WallPostException, :wall_context
48
+ rescue StandardError => e
49
+ puts e.readable_message # puts "We can not post to your wall"
50
+ end
51
+
52
+ begin
53
+ raise WallPostException, :friend_wall_context
54
+ rescue StandardError => e
55
+ puts e.readable_message # puts "We can not post to your friends wall"
56
+ end
57
+
58
+ begin
59
+ raise WallPostException::IntermittentError, :wall_context
60
+ rescue StandardError => e
61
+ puts e.readable_message # puts "We can not post to your wall right now. We'll try again later."
62
+ end
63
+
64
+ begin
65
+ raise WallPostException::IntermittentError, :friend_wall_context
66
+ rescue StandardError => e
67
+ puts e.readable_message # puts "We can not post to your friends wall"
68
+ end
69
+
70
+ begin
71
+ raise UnconfiguredException, :wall_context
72
+ rescue StandardError => e
73
+ puts e.readable_message # puts e.message
74
+ end
75
+
76
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,58 @@
1
+ require "yaml"
2
+
3
+ module ReadableExceptions
4
+
5
+ def self.setup(readable_msgs_file_path)
6
+ @@error_messages = parse_input(readable_msgs_file_path)
7
+
8
+ Exception.class_eval do
9
+ def readable_message(context = nil)
10
+ ::ReadableExceptions::readable_message(self, context)
11
+ end
12
+ end
13
+ end
14
+
15
+ def self.readable_message(exception, context = nil)
16
+ context ||= exception.message
17
+ return exception.message if ! valid_context?(context)
18
+
19
+ readable_message = message_for_context(exception.class, context)
20
+ return exception.message if readable_message.nil?
21
+
22
+ readable_message
23
+ end
24
+
25
+ private
26
+
27
+ def self.error_messages
28
+ @@error_messages
29
+ end
30
+
31
+ def self.parse_input(readable_msgs_file_path)
32
+ raise(ArgumentError, "Input file must be a readable") unless (File.readable?(readable_msgs_file_path) rescue false)
33
+
34
+ error_messages = (YAML::load(IO.read(readable_msgs_file_path))) rescue false
35
+ raise(ArgumentError, "Input file must be valid YAML") unless error_messages
36
+
37
+ error_messages
38
+ end
39
+
40
+ def self.valid_context?(context)
41
+ context.kind_of?(Hash) && context.size == 1
42
+ end
43
+
44
+ def self.message_for_context(klass, context)
45
+ return nil if klass.nil?
46
+
47
+ context_key = context.first[0].to_s
48
+ sub_context_key = context.first[1].to_s
49
+ klass_name = klass.name.to_s
50
+
51
+ if error_messages.has_key?(context_key) && error_messages[context_key].has_key?(klass_name) && error_messages[context_key][klass_name].has_key?(sub_context_key)
52
+ return error_messages[context_key][klass_name][sub_context_key]
53
+ end
54
+
55
+ message_for_context(klass.superclass, context)
56
+ end
57
+
58
+ end
@@ -0,0 +1,3 @@
1
+ module ReadableExceptions
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "readable_exceptions/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "readable_exceptions"
7
+ s.version = ReadableExceptions::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Chad Krsek"]
10
+ s.email = ["chad@contextoptional.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Easily configure human readable error messages for your exception classes, or for classses declared in libraries you use.}
13
+ s.description = %q{Easily configure human readable error messages for your exception classes, or for classses declared in libraries you use.}
14
+
15
+ s.rubyforge_project = "readable_exceptions"
16
+
17
+ s.add_dependency "rspec"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+ end
data/spec/empty.yml ADDED
File without changes
data/spec/example.yml ADDED
@@ -0,0 +1,12 @@
1
+ foo:
2
+ "An::Exception":
3
+ input_context: "There has been an input failure"
4
+ output_context: "There has been an output failure"
5
+
6
+ bar:
7
+ "Another::Exception":
8
+ print_context: "We can not print right now"
9
+ post_context: "We can not post right now"
10
+
11
+ "ChildException":
12
+ print_context: "We can print right now"
@@ -0,0 +1,124 @@
1
+ require "spec_helper"
2
+
3
+
4
+ # Declare classes that appear in yml input files
5
+ class An
6
+ class Exception < Exception
7
+ end
8
+ end
9
+
10
+ class Another
11
+ class Exception < Exception
12
+ end
13
+ end
14
+
15
+ class ChildException < Another::Exception
16
+ end
17
+
18
+ class YetAnother
19
+ class Exception < Exception
20
+ end
21
+ end
22
+
23
+
24
+ describe ReadableExceptions do
25
+
26
+ describe "should raise an exception when" do
27
+
28
+ it "input file is unreadable" do
29
+ lambda { ReadableExceptions.setup("") }.should raise_exception(ArgumentError)
30
+ end
31
+
32
+ it "input file is empty" do
33
+ lambda { ReadableExceptions.setup(File.dirname(__FILE__) + "/empty.yml") }.should raise_exception(ArgumentError)
34
+ end
35
+
36
+ end
37
+
38
+ describe "parses the input file" do
39
+
40
+ before :each do
41
+ ReadableExceptions.setup(File.dirname(__FILE__) + "/example.yml")
42
+ end
43
+
44
+ describe "returns the exception's message when" do
45
+
46
+ it "has no readable message context" do
47
+ e = An::Exception.new("test")
48
+ e.readable_message.should == "test"
49
+ end
50
+
51
+ it "the exception type does not have a readable message defined" do
52
+ e = YetAnother::Exception.new("test")
53
+ e.readable_message(:unknown => :context).should == "test"
54
+ end
55
+
56
+ it "the exception has a readable message defined but not in this context" do
57
+ e = An::Exception.new("test")
58
+ e.readable_message(:foo => :context).should == "test"
59
+ e = An::Exception.new("test")
60
+ e.readable_message(:baz => :input_context).should == "test"
61
+ end
62
+
63
+ it "neither the exception nor its parents have readable message defined for this context" do
64
+ e = ChildException.new("test")
65
+ e.readable_message(:unknown => :context).should == "test"
66
+ end
67
+
68
+ end
69
+
70
+ describe "returns the exception's readable message when" do
71
+
72
+ it "readable_message is called" do
73
+ An::Exception.new.readable_message.should == An::Exception.new.message
74
+ An::Exception.new.readable_message(:foo => :input_context).should == "There has been an input failure"
75
+ An::Exception.new.readable_message(:foo => :output_context).should == "There has been an output failure"
76
+ Another::Exception.new.readable_message(:bar => :print_context).should == "We can not print right now"
77
+ ChildException.new.readable_message(:bar => :print_context).should == "We can print right now"
78
+ Another::Exception.new.readable_message(:bar => :post_context).should == "We can not post right now"
79
+ ChildException.new.readable_message(:bar => :post_context).should == "We can not post right now"
80
+ end
81
+
82
+ it "an exception is instantiated with its message set to a readable message key" do
83
+ begin
84
+ raise An::Exception, :foo => :input_context
85
+ rescue Exception => e
86
+ e.readable_message.should == "There has been an input failure"
87
+ end
88
+
89
+ begin
90
+ raise An::Exception, :foo => :output_context
91
+ rescue Exception => e
92
+ e.readable_message.should == "There has been an output failure"
93
+ end
94
+
95
+ begin
96
+ raise Another::Exception, :bar => :print_context
97
+ rescue Exception => e
98
+ e.readable_message.should == "We can not print right now"
99
+ end
100
+
101
+ begin
102
+ raise ChildException, :bar => :print_context
103
+ rescue Exception => e
104
+ e.readable_message.should == "We can print right now"
105
+ end
106
+
107
+ begin
108
+ raise Another::Exception, :bar => :post_context
109
+ rescue Exception => e
110
+ e.readable_message.should == "We can not post right now"
111
+ end
112
+
113
+ begin
114
+ raise ChildException, :bar => :post_context
115
+ rescue Exception => e
116
+ e.readable_message.should == "We can not post right now"
117
+ end
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -0,0 +1,2 @@
1
+ $:.push(File.dirname(__FILE__) + "/../lib/")
2
+ require "readable_exceptions"
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: readable_exceptions
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Chad Krsek
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-04-20 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ description: Easily configure human readable error messages for your exception classes, or for classses declared in libraries you use.
34
+ email:
35
+ - chad@contextoptional.com
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files: []
41
+
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - README.md
46
+ - Rakefile
47
+ - lib/readable_exceptions.rb
48
+ - lib/readable_exceptions/version.rb
49
+ - readable_exceptions.gemspec
50
+ - spec/empty.yml
51
+ - spec/example.yml
52
+ - spec/readable_exceptions_spec.rb
53
+ - spec/spec_helper.rb
54
+ has_rdoc: true
55
+ homepage: ""
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ requirements: []
80
+
81
+ rubyforge_project: readable_exceptions
82
+ rubygems_version: 1.3.7
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Easily configure human readable error messages for your exception classes, or for classses declared in libraries you use.
86
+ test_files:
87
+ - spec/empty.yml
88
+ - spec/example.yml
89
+ - spec/readable_exceptions_spec.rb
90
+ - spec/spec_helper.rb