errational 0.7.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.
Files changed (70) hide show
  1. data/Gemfile +9 -0
  2. data/Gemfile.lock +80 -0
  3. data/README +0 -0
  4. data/Rakefile +12 -0
  5. data/errational.gemspec +20 -0
  6. data/lib/errational.rb +34 -0
  7. data/lib/errational/errationalify.rb +86 -0
  8. data/lib/errational/errationality.rb +37 -0
  9. data/lib/errational/test_helpers.rb +11 -0
  10. data/lib/errational/version.rb +3 -0
  11. data/lib/generators/errational/install_generator.rb +34 -0
  12. data/lib/generators/templates/_error_dialog.js.erb +20 -0
  13. data/lib/generators/templates/errational_configuration.rb +18 -0
  14. data/lib/generators/templates/error_module.rb +53 -0
  15. data/lib/generators/templates/exception_module.rb +25 -0
  16. data/test/errational_test.rb +51 -0
  17. data/test/errationalify_test.rb +23 -0
  18. data/test/errationality_test.rb +69 -0
  19. data/test/generators/install_generator_test.rb +16 -0
  20. data/test/rails_app/.gitignore +4 -0
  21. data/test/rails_app/README +256 -0
  22. data/test/rails_app/Rakefile +7 -0
  23. data/test/rails_app/app/controllers/application_controller.rb +3 -0
  24. data/test/rails_app/app/helpers/application_helper.rb +2 -0
  25. data/test/rails_app/app/views/_error_dialog.js.erb +1 -0
  26. data/test/rails_app/app/views/layouts/application.html.erb +14 -0
  27. data/test/rails_app/config.ru +4 -0
  28. data/test/rails_app/config/application.rb +48 -0
  29. data/test/rails_app/config/boot.rb +9 -0
  30. data/test/rails_app/config/database.yml +22 -0
  31. data/test/rails_app/config/environment.rb +5 -0
  32. data/test/rails_app/config/environments/development.rb +26 -0
  33. data/test/rails_app/config/environments/production.rb +49 -0
  34. data/test/rails_app/config/environments/test.rb +35 -0
  35. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  36. data/test/rails_app/config/initializers/errational_configuration.rb +6 -0
  37. data/test/rails_app/config/initializers/inflections.rb +10 -0
  38. data/test/rails_app/config/initializers/mime_types.rb +5 -0
  39. data/test/rails_app/config/initializers/secret_token.rb +7 -0
  40. data/test/rails_app/config/initializers/session_store.rb +8 -0
  41. data/test/rails_app/config/locales/en.yml +5 -0
  42. data/test/rails_app/config/routes.rb +59 -0
  43. data/test/rails_app/db/seeds.rb +7 -0
  44. data/test/rails_app/doc/README_FOR_APP +2 -0
  45. data/test/rails_app/lib/rails_app_error.rb +54 -0
  46. data/test/rails_app/lib/rails_app_exception.rb +25 -0
  47. data/test/rails_app/lib/tasks/.gitkeep +0 -0
  48. data/test/rails_app/public/404.html +26 -0
  49. data/test/rails_app/public/422.html +26 -0
  50. data/test/rails_app/public/500.html +26 -0
  51. data/test/rails_app/public/favicon.ico +0 -0
  52. data/test/rails_app/public/images/rails.png +0 -0
  53. data/test/rails_app/public/index.html +239 -0
  54. data/test/rails_app/public/javascripts/application.js +2 -0
  55. data/test/rails_app/public/javascripts/controls.js +965 -0
  56. data/test/rails_app/public/javascripts/dragdrop.js +974 -0
  57. data/test/rails_app/public/javascripts/effects.js +1123 -0
  58. data/test/rails_app/public/javascripts/prototype.js +6001 -0
  59. data/test/rails_app/public/javascripts/rails.js +191 -0
  60. data/test/rails_app/public/robots.txt +5 -0
  61. data/test/rails_app/public/stylesheets/.gitkeep +0 -0
  62. data/test/rails_app/script/rails +6 -0
  63. data/test/rails_app/test/test_helper.rb +13 -0
  64. data/test/rails_app/vendor/plugins/.gitkeep +0 -0
  65. data/test/test_helper.rb +10 -0
  66. data/test/tmp/app/views/errational/_error_dialog.js.erb +20 -0
  67. data/test/tmp/config/initializers/errational_configuration.rb +18 -0
  68. data/test/tmp/lib/errational/rails_app_error.rb +53 -0
  69. data/test/tmp/lib/errational/rails_app_exception.rb +25 -0
  70. metadata +171 -0
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in errational.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "0.8.7"
7
+ gem "rails", "3.0.7"
8
+ gem "mocha", '0.9.12', :require => false
9
+
data/Gemfile.lock ADDED
@@ -0,0 +1,80 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ errational (0.7.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ abstract (1.0.0)
10
+ actionmailer (3.0.7)
11
+ actionpack (= 3.0.7)
12
+ mail (~> 2.2.15)
13
+ actionpack (3.0.7)
14
+ activemodel (= 3.0.7)
15
+ activesupport (= 3.0.7)
16
+ builder (~> 2.1.2)
17
+ erubis (~> 2.6.6)
18
+ i18n (~> 0.5.0)
19
+ rack (~> 1.2.1)
20
+ rack-mount (~> 0.6.14)
21
+ rack-test (~> 0.5.7)
22
+ tzinfo (~> 0.3.23)
23
+ activemodel (3.0.7)
24
+ activesupport (= 3.0.7)
25
+ builder (~> 2.1.2)
26
+ i18n (~> 0.5.0)
27
+ activerecord (3.0.7)
28
+ activemodel (= 3.0.7)
29
+ activesupport (= 3.0.7)
30
+ arel (~> 2.0.2)
31
+ tzinfo (~> 0.3.23)
32
+ activeresource (3.0.7)
33
+ activemodel (= 3.0.7)
34
+ activesupport (= 3.0.7)
35
+ activesupport (3.0.7)
36
+ arel (2.0.10)
37
+ builder (2.1.2)
38
+ erubis (2.6.6)
39
+ abstract (>= 1.0.0)
40
+ i18n (0.5.0)
41
+ mail (2.2.19)
42
+ activesupport (>= 2.3.6)
43
+ i18n (>= 0.4.0)
44
+ mime-types (~> 1.16)
45
+ treetop (~> 1.4.8)
46
+ mime-types (1.16)
47
+ mocha (0.9.12)
48
+ polyglot (0.3.1)
49
+ rack (1.2.3)
50
+ rack-mount (0.6.14)
51
+ rack (>= 1.0.0)
52
+ rack-test (0.5.7)
53
+ rack (>= 1.0)
54
+ rails (3.0.7)
55
+ actionmailer (= 3.0.7)
56
+ actionpack (= 3.0.7)
57
+ activerecord (= 3.0.7)
58
+ activeresource (= 3.0.7)
59
+ activesupport (= 3.0.7)
60
+ bundler (~> 1.0)
61
+ railties (= 3.0.7)
62
+ railties (3.0.7)
63
+ actionpack (= 3.0.7)
64
+ activesupport (= 3.0.7)
65
+ rake (>= 0.8.7)
66
+ thor (~> 0.14.4)
67
+ rake (0.8.7)
68
+ thor (0.14.6)
69
+ treetop (1.4.9)
70
+ polyglot (>= 0.3.1)
71
+ tzinfo (0.3.29)
72
+
73
+ PLATFORMS
74
+ ruby
75
+
76
+ DEPENDENCIES
77
+ errational!
78
+ mocha (= 0.9.12)
79
+ rails (= 3.0.7)
80
+ rake (= 0.8.7)
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ require 'rake/testtask'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ desc 'Run Errational unit tests.'
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << 'lib'
9
+ t.libs << 'test'
10
+ t.pattern = 'test/**/*_test.rb'
11
+ t.verbose = true
12
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "errational/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "errational"
7
+ s.version = Errational::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Kate Gengler", "Brian Olore"]
10
+ s.email = ["errational@surrationale.net"]
11
+ s.summary = %q{A gem for nice exception handling.}
12
+ s.description = %q{Nice error handling}
13
+
14
+ s.rubyforge_project = "errational"
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
+ end
data/lib/errational.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'rails'
2
+ require 'rails/generators'
3
+ require 'active_support/dependencies'
4
+ require 'errational/errationality'
5
+ require 'errational/errationalify'
6
+ require 'generators/errational/install_generator'
7
+
8
+ module Errational
9
+
10
+ def self.setup
11
+ yield self
12
+ end
13
+
14
+ mattr_accessor :namespace
15
+ mattr_accessor :error_response_code
16
+ mattr_accessor :error_partial
17
+ mattr_accessor :logger
18
+
19
+ def self.error_base_name
20
+ "#{Errational.namespace}Error"
21
+ end
22
+
23
+ def self.exception_base_name
24
+ "#{Errational.namespace}Exception"
25
+ end
26
+
27
+ def self.error_base
28
+ Kernel.const_get(Errational.error_base_name)
29
+ end
30
+
31
+ def self.exception_base
32
+ Kernel.const_get(Errational.exception_base_name)
33
+ end
34
+ end
@@ -0,0 +1,86 @@
1
+ module Errationalify
2
+
3
+ class Parent < RuntimeError;
4
+ end
5
+
6
+ class Loggable < Parent
7
+ def initialize(message = "")
8
+ super(message)
9
+ end
10
+ end
11
+
12
+ def self.included(module_that_has_included_this_module)
13
+ create_classes_from_constants_in_modules_within_error_module
14
+ end
15
+
16
+
17
+ def self.error_class(message = "", parent = Parent, &block)
18
+ block ||= Proc.new do
19
+ define_method(:initialize) { super(message) }
20
+ end
21
+ Class.new(parent, &block)
22
+ end
23
+
24
+ def self.intermediate_class
25
+ lambda {
26
+ error_class do
27
+ def initialize(message = "")
28
+ super(message)
29
+ end
30
+ end
31
+ }
32
+ end
33
+
34
+ def self.create_classes_from_constants_in_modules_within_error_module
35
+ sub_modules = modules_in(Errational.error_base)
36
+ sub_modules.each do |module_name|
37
+ current_module = Errational.error_base.const_get(module_name)
38
+ create_classes_from_constants_in(current_module)
39
+ end
40
+ end
41
+
42
+ def self.create_classes_from_constants_in(current_module)
43
+ current_module.constants.each do |constant_name|
44
+ error_constant = current_module.const_get(constant_name)
45
+ error_class_name = classify_name(constant_name)
46
+ parent_class = parent_class_for(current_module)
47
+ create_error_class_with(error_class_name, error_constant, parent_class)
48
+ end
49
+ end
50
+
51
+ def self.parent_class_for(current_module)
52
+ parent_class_name = name_of(current_module)
53
+
54
+ if already_a_class_on_the_class_that_has_included_this_module?(parent_class_name)
55
+ parent_class = Errational.exception_base.const_get(parent_class_name)
56
+ else
57
+ parent_class = Errational.exception_base.const_set(parent_class_name, intermediate_class.call)
58
+ end
59
+ parent_class
60
+ end
61
+
62
+ def self.already_a_class_on_the_class_that_has_included_this_module?(module_name)
63
+ included_in_constants?(Errational.exception_base, module_name) && defined?(Errational.exception_base.const_get(module_name)) && Errational.exception_base.const_get(module_name).is_a?(Class)
64
+ end
65
+
66
+ def self.name_of(current_module)
67
+ current_module.name.split("::").second
68
+ end
69
+
70
+ def self.create_error_class_with(class_name, constant, parent)
71
+ Errational.exception_base.const_set(class_name, error_class(constant, parent))
72
+ end
73
+
74
+ def self.classify_name(constant_name)
75
+ constant_name.to_s.downcase.camelize
76
+ end
77
+
78
+ def self.included_in_constants?(mod, constant_name)
79
+ mod.constants.include? constant_name
80
+ end
81
+
82
+ def self.modules_in(mod)
83
+ mod.constants.select { |name| mod.const_get(name).is_a? Module }
84
+ end
85
+
86
+ end
@@ -0,0 +1,37 @@
1
+ module Errationality
2
+ private
3
+
4
+ def handle_unexpected_exception(exception)
5
+ log_exception(exception)
6
+ handle_exception(Errational.error_base::UNEXPECTED)
7
+ end
8
+
9
+ def handle_exception(exception_or_message)
10
+ log_exception(exception_or_message) if (exception_or_message.is_a? Errational.exception_base::Loggable)
11
+ render_error(exception_or_message.to_s)
12
+ end
13
+
14
+ def render_error(message)
15
+ if request.xhr?
16
+ render :partial => Errational.error_partial, :status => Errational.error_response_code, :locals => {:message => message}
17
+ else
18
+ render :text => message, :status => Errational.error_response_code
19
+ end
20
+ end
21
+
22
+ def log_exception(exception)
23
+ Errational.logger.info "An exception occurred and was handled #{exception.class} : #{exception.to_s}"
24
+ Errational.logger.info exception.backtrace[0, 15].join("\n")
25
+ end
26
+ end
27
+
28
+
29
+ # Note:
30
+ # When using rescue_from, assert_raises no longer works
31
+ # Test for the results of the exception handling or expect exception handlers to be called
32
+ ActiveSupport.on_load(:action_controller) do
33
+ include Errationality
34
+
35
+ rescue_from Exception, :with => :handle_unexpected_exception
36
+ rescue_from Errational.exception_base::Parent, :with => :handle_exception
37
+ end
@@ -0,0 +1,11 @@
1
+ module Errational
2
+ module TestHelpers
3
+ def assert_renders_error_message(error)
4
+ assert_match @response.body, /#{error}/
5
+ end
6
+
7
+ def expect_no_error
8
+ @controller.expects(:handle_exception).never
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Errational
2
+ VERSION = "0.7.1"
3
+ end
@@ -0,0 +1,34 @@
1
+ module Errational
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::NamedBase
4
+
5
+ desc "This generator will create the necessary exception and error files in the lib/errational directory"
6
+
7
+ source_root File.expand_path("../../templates", __FILE__)
8
+
9
+ def print_message
10
+ puts "Installing errational..."
11
+ end
12
+
13
+ def create_error_file
14
+ @error_module_name = "#{class_name}Error"
15
+ template("error_module.rb", "lib/errational/#{file_name}_error.rb")
16
+ end
17
+
18
+ def create_exception_file
19
+ @exception_module_name = "#{class_name}Exception"
20
+ template("exception_module.rb", "lib/errational/#{file_name}_exception.rb")
21
+ end
22
+
23
+ def create_configuration_file
24
+ @namespace = class_name
25
+ template("errational_configuration.rb", "config/initializers/errational_configuration.rb")
26
+ end
27
+
28
+ def create_partial_file
29
+ template("_error_dialog.js.erb", "app/views/errational/_error_dialog.js.erb")
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,20 @@
1
+ /*
2
+ * This is the partial to be used for exceptions handled as the result of xhr actions
3
+ *
4
+ * where 'message' is the text from <%=file_name%>_error.rb
5
+ *
6
+ */
7
+ jQuery('body').append('<div id="errational_error_dialog"></div>');
8
+ jQuery('#errational_error_dialog')
9
+ .html('<%%= message %>')
10
+ .dialog(
11
+ {
12
+ minHeight: 'auto',
13
+ height: 'auto',
14
+ modal: true,
15
+ dialogClass: 'errational_class',
16
+ title: 'Error!',
17
+ resizable: false,
18
+ width: 450
19
+ }
20
+ );
@@ -0,0 +1,18 @@
1
+ #TODO is this the best place for this line?
2
+ ActiveSupport::Dependencies.autoload_paths << "#{Rails.root}/lib/errational"
3
+
4
+ Errational.setup do |config|
5
+ # Namespace for name of exception and error modules, based on the name given at install time.
6
+ # Note, if changing, change the module names in lib/namespace_error.rb and lib/namespace_exception.rb,
7
+ # , as well as the filenames
8
+ config.namespace = "<%= @namespace %>"
9
+
10
+ # The response code given for exceptions that are handled.
11
+ config.error_response_code = 203
12
+
13
+ # The partial to be used for exceptions handled as the result of xhr actions
14
+ config.error_partial = '/errational/error_dialog'
15
+
16
+ # The logger to be used for NamespaceException::Loggable exceptions and unexpected exceptions
17
+ config.logger = Rails.logger
18
+ end
@@ -0,0 +1,53 @@
1
+ # This module contains modules of error constants, from each constant an exception class will be generated.
2
+ # Each submodule will be created as a class; it will be used as an intermediate ancestor between the exception class
3
+ # and the application exception class.
4
+ # For example, where Application is the name of the application:
5
+ # module ApplicationError
6
+ # module General
7
+ # UNEXPECTED = "An error has occurred in the application. Please try again."
8
+ # end
9
+ # module Loggable
10
+ # SERVICE_FAULT = "The response from the service cannot be processed. Please try again"
11
+ # end
12
+ # module Serious
13
+ # BAD_PROBLEM = "The server is on fire, please call the fire department"
14
+ # end
15
+ # end
16
+ #
17
+ # class FirstController < ApplicationController
18
+ # def index
19
+ # raise ApplicationException::ServiceFault # Will automatically be handled by the error handling gem with corresponding message.
20
+ # end
21
+ #
22
+ # def create
23
+ # raise RuntimeError # Will automatically be handled by error handling gem with UNEXPECTED message.
24
+ # end
25
+ #
26
+ # def update
27
+ # raise ApplicationException::BadProblem
28
+ # rescue ApplicationException::Parent => e # Will rescue any of the exceptions generated by the plugin.
29
+ # if(e.is_a? ApplicationException::Serious) # Sub modules are created as ancestor classes of exceptions, useful for special casing.
30
+ # call_lead_developer
31
+ # end
32
+ # end
33
+ # end
34
+ #
35
+ module <%= @error_module_name %>
36
+
37
+ module General
38
+ # Default message for all general exceptions.
39
+ # Unexpected exceptions (ones without specific exception classes) will be logged.
40
+ UNEXPECTED = "An error has occurred with your last request. Please try again."
41
+ end
42
+
43
+ #Errors in this special module will be logged
44
+ module Loggable
45
+ end
46
+
47
+
48
+ def self.include_all_of_own_modules
49
+ constants.map { |c| const_get(c) }.select { |c| Module === c }.each { |c| include c }
50
+ end
51
+
52
+ include_all_of_own_modules
53
+ end
@@ -0,0 +1,25 @@
1
+ # This module is where you can override the default behavior of exception classes or add other exception classes.
2
+ # The default behavior of the exception classes is to create an exception with the message of the constant.
3
+ # Exception classes that override generated exception classes must be defined as children of their parent module's generated class.
4
+ # Example:
5
+ # module ApplicationException
6
+ # include ErrorHandlingClass
7
+ #
8
+ # class ServiceFault < Loggable
9
+ # def initialize(service_name)
10
+ # message = sprintf(ApplicationError::SERVICE_FAULT, service_name)
11
+ # end
12
+ # end
13
+ # end
14
+ # module ApplicationError
15
+ # module General
16
+ # UNEXPECTED = "An error has occurred in the application. Please try again."
17
+ # end
18
+ # module Loggable
19
+ # SERVICE_FAULT = "The response from %s cannot be processed. Please try again"
20
+ # end
21
+ # end
22
+
23
+ module <%= @exception_module_name %>
24
+ include Errationalify
25
+ end