errational 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
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