exception_handler 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +4 -4
  4. data/Gemfile +1 -3
  5. data/README.md +111 -98
  6. data/app/assets/images/exception_handler/connect/facebook.png +0 -0
  7. data/app/assets/images/exception_handler/connect/fusion.png +0 -0
  8. data/app/assets/images/exception_handler/connect/linkedin.png +0 -0
  9. data/app/assets/images/exception_handler/connect/twitter.png +0 -0
  10. data/app/assets/images/exception_handler/connect/youtube.png +0 -0
  11. data/app/assets/images/exception_handler/noise.png +0 -0
  12. data/app/assets/images/favicon.ico +0 -0
  13. data/app/assets/stylesheets/exception_handler.css.erb +18 -0
  14. data/app/assets/stylesheets/styles/_base.css.erb +34 -0
  15. data/app/assets/stylesheets/styles/_exception.css.erb +105 -0
  16. data/app/assets/stylesheets/styles/_footer.css.erb +27 -0
  17. data/app/assets/stylesheets/styles/_responsive.css +5 -0
  18. data/app/controllers/exception_handler/exception_controller.rb +28 -33
  19. data/app/mailers/exception_handler/exception_mailer.rb +17 -0
  20. data/app/models/exception_handler/exception.rb +191 -0
  21. data/app/views/exception_handler/exception/show.html.erb +3 -32
  22. data/app/views/exception_handler/mailers/layout.haml +8 -0
  23. data/app/views/exception_handler/mailers/layout.text.erb +1 -0
  24. data/app/views/exception_handler/mailers/new_exception.erb +4 -0
  25. data/app/views/layouts/exception.html.erb +15 -23
  26. data/config/locales/exception_handler.en.yml +13 -0
  27. data/exception_handler.gemspec +61 -16
  28. data/lib/exception_handler.rb +20 -79
  29. data/lib/exception_handler/config.rb +20 -22
  30. data/lib/exception_handler/engine.rb +36 -0
  31. data/lib/generators/exception_handler/migration_generator.rb +28 -10
  32. data/lib/generators/exception_handler/views_generator.rb +5 -5
  33. data/lib/generators/templates/migration.rb.erb +12 -11
  34. metadata +41 -64
  35. data/app/assets/images/exception_handler/close.png +0 -0
  36. data/app/assets/images/exception_handler/home.png +0 -0
  37. data/app/assets/stylesheets/exception_handler/error.css.erb +0 -309
  38. data/app/helpers/exception_handler/application_helper.rb +0 -56
  39. data/app/models/exception_handler/error.rb +0 -14
  40. data/app/services/exception_handler/exception.rb +0 -34
  41. data/config/locales/en.yml +0 -9
  42. data/lib/exception_handler/parse.rb +0 -23
  43. data/lib/exception_handler/parser/data.rb +0 -59
  44. data/lib/exception_handler/parser/ignore.rb +0 -32
  45. data/lib/exception_handler/version.rb +0 -3
  46. data/post_install_message.md +0 -53
  47. data/spec/helpers/exception_handler/application_helper_spec.rb +0 -42
@@ -0,0 +1,8 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/
5
+ :css
6
+ /* Email styles need to be inline */
7
+ %body
8
+ = yield
@@ -0,0 +1,4 @@
1
+ <h1><%= Rails.application.class.parent_name %> (<%= Rails.env.titleize %>)</h1>
2
+
3
+ <strong><u><%= @exception.response %> (<%= @exception.status %>)</u></strong>
4
+ <p><%= @exception.message %></p>
@@ -1,29 +1,21 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
+ <!-- Head -->
3
4
  <head>
4
-
5
- <!--Info -->
6
- <title><%= "Error - #{@exception.status} Error (#{details[:name]})" %></title>
7
- <%= stylesheet_link_tag "exception_handler/error" %>
8
-
5
+ <%= content_tag :title, "Error - #{@exception.status} (#{@exception.response.to_s.gsub("_", " ").titleize})" %>
6
+ <%= stylesheet_link_tag :exception_handler %>
7
+ <%= favicon_link_tag %>
9
8
  </head>
10
-
11
- <!--Body -->
12
- <body>
13
- <div class="container">
14
- <%= yield %>
15
- </div>
16
9
 
17
- <!-- Footer -->
18
- <footer>
19
- <div class="connect">
20
- <%= social %>
21
- </div>
22
- <div class="app">
23
- <strong><%= link_to app, main_app.root_url, title: "Go to index" %></strong>
24
- <span> - <%= @exception.status %> Error</span>
25
- </div>
26
- </footer>
10
+ <!-- Body -->
11
+ <%= content_tag :body, yield %>
27
12
 
28
- </body>
29
- </html>
13
+ <!-- Footer -->
14
+ <% if ExceptionHandler.config.try(:social) %>
15
+ <%= content_tag :footer do %>
16
+ <% ExceptionHandler.config.social.each do |k,v| %>
17
+ <%= link_to image_tag("exception_handler/connect/#{k}.png"), v[:url] + "/" + v[:name], id: v[:name] if v %>
18
+ <% end %>
19
+ <% end %>
20
+ <% end %>
21
+ </html>
@@ -0,0 +1,13 @@
1
+ ##################################
2
+ ##################################
3
+ # Have to use strings rather than integers
4
+ ##################################
5
+ ##################################
6
+
7
+ en:
8
+ exception:
9
+ not_found: "Page missing"
10
+ internal_server_error: "<strong>Our server experienced an error. Our developers have been notified and are resolving it:</strong> %{message}"
11
+
12
+ ##################################
13
+ ##################################
@@ -1,21 +1,56 @@
1
- # coding: utf-8
1
+ # Dependencies
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'exception_handler/version'
5
4
 
5
+ ##############################################################
6
+ ##############################################################
7
+
8
+ # => Version
9
+ # => https://github.com/rails/rails/blob/master/version.rb
10
+ module ExceptionHandler
11
+ module VERSION
12
+ MAJOR = 0
13
+ MINOR = 6
14
+ TINY = 0
15
+ PRE = nil # "alpha"
16
+
17
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
18
+ end
19
+ end
20
+
21
+ # => Declaration
22
+ # => https://github.com/rails/rails/blob/master/rails.gemspec#L1
23
+ version = ExceptionHandler::VERSION::STRING
24
+
25
+ ##############################################################
26
+ ##############################################################
27
+
28
+ # => Gem
6
29
  Gem::Specification.new do |s|
7
30
 
8
- # General
31
+ ##############################################################
32
+
33
+ # => General
34
+ s.platform = Gem::Platform::RUBY
9
35
  s.name = "exception_handler"
10
- s.version = ExceptionHandler::VERSION
36
+ s.version = version
37
+
38
+ # => Author
11
39
  s.authors = ["Richard Peck"]
12
40
  s.email = ["rpeck@frontlineutilities.co.uk"]
41
+
42
+ # => Details
13
43
  s.summary = %q{Rails gem to show custom error pages in production. Also logs errors in db & sends notification emails}
14
44
  s.description = %q{Rails gem to create custom error pages. Captures exceptions using "exception_app" callback, routing to "Exception" controller, rendering the view as required.}
15
45
  s.homepage = "http://github.com/richpeck/exception_handler"
46
+
47
+ # => License
16
48
  s.license = "MIT"
17
49
 
18
- # Files
50
+ ##############################################################
51
+
52
+ # => Files
53
+ # => Remove "readme" dir from gem
19
54
  s.files = `git ls-files -z`.split("\x0")
20
55
  s.files.reject! { |fn| fn.include? "readme" } #-> https://github.com/gauntlt/gauntlt/blob/master/gauntlt.gemspec#L16
21
56
 
@@ -23,17 +58,27 @@ Gem::Specification.new do |s|
23
58
  s.test_files = s.files.grep(%r{^(test|spec|features)/}) unless RUBY_VERSION >= "2.2.0" #-> deprecated in Ruby 2.2.0
24
59
  s.require_paths = ["lib"]
25
60
 
26
- # Options
27
- s.post_install_message = File.read(File.join(File.dirname(__FILE__), 'post_install_message.md')) #-> https://github.com/jarrett/ichiban/blob/master/ichiban.gemspec#L35
61
+ ##############################################################
62
+
63
+ # => Ruby
64
+ s.required_ruby_version = ">= 2.1.0"
28
65
 
29
- # dev Dependencies
30
- s.add_development_dependency "bundler", "~> 1.6"
31
- s.add_development_dependency "rails", "~> 4.0.0"
32
- s.add_development_dependency "activerecord"
33
- s.add_development_dependency "activesupport"
66
+ # => Runtime
67
+ s.add_dependency "bundler", "~> 1.6"
68
+ s.add_dependency "rails", ">= 4.2.0"
69
+ s.add_dependency "responders", "~> 2.3"
70
+
71
+ # => Extras
72
+ s.add_development_dependency "autoprefixer-rails"
73
+
74
+ # => Dev
75
+ # => For testing etc
34
76
  s.add_development_dependency "rake"
35
- s.add_development_dependency "rspec", "~> 3.3"
36
- s.add_development_dependency "rspec-rails", "~> 3.3"
37
- s.add_development_dependency "sqlite3", "~> 1.3.10"
77
+ s.add_development_dependency "rspec"
78
+ s.add_development_dependency "rspec-rails"
79
+ s.add_development_dependency "sqlite3", ">= 1.3.10"
80
+
81
+ ##############################################################
82
+ ##############################################################
38
83
 
39
- end
84
+ end
@@ -1,88 +1,29 @@
1
- ###########################################
2
-
3
- #Core Dependencies
4
- require "action_dispatch"
5
-
6
- #Libs
7
- #http://stackoverflow.com/a/4528011/1143732
8
- #http://stackoverflow.com/a/21693468/1143732
9
- #https://github.com/jekyll/jekyll/blob/master/lib/jekyll.rb#L8
10
- Dir.glob(File.join(File.dirname(__FILE__), "exception_handler", '**/*.rb'), &method(:require))
11
-
12
- ###########################################
1
+ #########################################################
2
+ #########################################################
13
3
 
14
4
  module ExceptionHandler
15
5
 
16
- #Config
17
- #Invoke instance of config (ExceptionHandler.config) -- loads defaults -- can merge through class
18
- mattr_accessor :config
19
-
20
- #Default (has to init so is available in all areas)
21
- @@config = "" #-> should initialize class & then append in initializer
22
-
23
- # Class methods
24
- class << self
25
- # Don't have prefix method return anything.
26
- # This will keep Rails Engine from generating all table prefixes with the engines name
27
- # http://stackoverflow.com/questions/19435214/rails-mountable-engine-with-isolate-namespace-but-without-prefixed-namespace-on
28
- def table_name_prefix
29
- #No prefix
30
- end
6
+ # => Table Prefix
7
+ # => Keeps Rails Engine from generating all table prefixes with the engines name
8
+ # => http://stackoverflow.com/questions/19435214/rails-mountable-engine-with-isolate-namespace-but-without-prefixed-namespace-on
9
+ def self.table_name_prefix
10
+ # => No prefix
31
11
  end
32
12
 
33
- #########################
34
-
35
- #Exception Handler
36
- class Engine < Rails::Engine
37
- #Keep helpers in your engine
38
- #http://guides.rubyonrails.org/engines.html#inside-an-engine
39
- #http://stackoverflow.com/questions/31877839/accessing-helpers-from-the-parent-app-in-an-isolated-rails-engine
40
- #use main_app to call "main app" helpers etc http://stackoverflow.com/a/9178022/1143732 + http://edgeapi.rubyonrails.org/classes/Rails/Engine.html#class-Rails::Engine-label-Using+Engine-27s+routes+outside+Engine
41
- isolate_namespace ExceptionHandler
42
-
43
- #Tests (generates dummy Rails app)
44
- #http://stackoverflow.com/q/32082637/1143732 (ref in question)
45
- config.generators do |g|
46
- g.test_framework :rspec
47
- end
48
-
49
- #Assets
50
- config.assets.precompile << %w(exception_handler/**)
51
-
52
- #Config
53
- config.before_initialize do |app|
54
- ExceptionHandler.config = ExceptionHandler::Config.new app.config.try(:exception_handler) #-> Var
55
- end
56
-
57
- #Boot order:
58
- #http://api.rubyonrails.org/classes/Rails/Application.html#class-Rails::Application-label-Booting+process
59
- #1) require "config/boot.rb" to setup load paths
60
- #2) require railties and engines
61
- #3) Define Rails.application as "class MyApp::Application < Rails::Application"
62
- #4) Run config.before_configuration callbacks
63
- #5) Load config/environments/ENV.rb
64
- #6) Run config.before_initialize callbacks
65
- #7) Run Railtie#initializer defined by railties, engines and application.
66
- # One by one, each engine sets up its load paths, routes and runs its config/initializers/* files.
67
- #8) Custom Railtie#initializers added by railties, engines and applications are executed
68
- #9) Build the middleware stack and run to_prepare callbacks
69
- #10) Run config.before_eager_load and eager_load! if eager_load is true
70
- #11) Run config.after_initialize callbacks
71
-
72
- #Hook
73
- #Needs to fire before better_errors (for dev)
74
- initializer :exception_handler, before: "better_errors.configure_rails_initialization" do |app| #-> "before" ref - http://blog.carbonfive.com/2011/02/25/configure-your-gem-the-rails-way-with-railtie/ && http://apidock.com/rails/Rails/Initializable/Initializer/before - should degrade gracefully
13
+ # => Config
14
+ # => Invoke instance of config (ExceptionHandler.config)
15
+ mattr_accessor :config
75
16
 
76
- #Action
77
- app.config.middleware.use ExceptionHandler::Parse if ExceptionHandler.config.try(:db) #-> DB
78
- app.config.exceptions_app = ->(env) { ExceptionHandler::ExceptionController.action(:show).call(env) } #-> Controller
17
+ end
79
18
 
80
- #Dev
81
- #Logic needed after initialize (app data)
82
- app.config.consider_all_requests_local = false if Rails.env.development? and ExceptionHandler.config.try(:dev)
83
- end
19
+ #########################################################
20
+ #########################################################
84
21
 
85
- end
86
- end
22
+ # => Libs
23
+ # => http://stackoverflow.com/a/4528011/1143732
24
+ # => http://stackoverflow.com/a/21693468/1143732
25
+ # => https://github.com/jekyll/jekyll/blob/master/lib/jekyll.rb#L8
26
+ Dir.glob(File.join(File.dirname(__FILE__), 'exception_handler', '**/*.rb'), &method(:require))
87
27
 
88
- ###########################################
28
+ #########################################################
29
+ #########################################################
@@ -16,17 +16,23 @@ module ExceptionHandler
16
16
 
17
17
  #Init
18
18
  def initialize values=nil
19
- defaults = values.present? ? Config::DEFAULTS.deep_merge!(values) : Config::DEFAULTS
19
+ defaults = values.present? ? Config::DEFAULTS.deep_merge!(values) : DEFAULTS
20
20
  defaults.each do |k,v|
21
- instance_variable_set("@#{k}",v) #-> http://apidock.com/ruby/Object/instance_variable_set
21
+ instance_variable_set("@#{k}",v) #-> http://apidock.com/ruby/Object/instance_variable_set
22
22
  end
23
+
24
+ # => Errors
25
+ raise(Exception, "ExceptionHandler :: Valid Email Required") if @email && !@email.is_a?(String)
26
+ #raise(Exception, "ExceptionHandler :: Migration Required → Table \"#{db}\" doesn't exist") if @db && !ActiveRecord::Base.connection.table_exists?(db)
23
27
  end
24
28
 
25
- # INSTANCE METHODS #
29
+ ###########################################
30
+
31
+ # Public (Instance) Methods #
26
32
 
27
33
  #DB
28
34
  def db
29
- @db == true ? Config::TABLE_NAME : @db
35
+ @db == true ? TABLE_NAME : @db
30
36
  end
31
37
 
32
38
  ###########################################
@@ -38,31 +44,23 @@ module ExceptionHandler
38
44
  # Defaults
39
45
  # http://stackoverflow.com/a/8917301/1143732
40
46
  DEFAULTS = {
41
- dev: false, #-> defaults to "false" for dev mode
47
+ dev: false, #-> defaults to "false" for dev mode
42
48
  db: false, #-> defaults to :errors if true, else use "table_name" / :table_name
43
- email: false, #-> need to integrate
49
+ email: false, #-> requires string email and ActionMailer
44
50
  social: {
45
- :facebook => 'frontline.utilities',
46
- :twitter => 'frontlineutils',
47
- :youtube => 'frontlineutils',
48
- :linkedin => 'frontline-utilities',
49
- :fusion => 'frontlineutils',
50
- :url => {
51
- :facebook => 'https://facebook.com',
52
- :twitter => 'http://twitter.com',
53
- :youtube => 'https://youtube.com/user',
54
- :linkedin => 'https://linkedin.com/company',
55
- :fusion => 'https://frontlinefusion.com',
56
- },
51
+ facebook: { name: "frontline.utilities", url: "https://facebook.com" },
52
+ twitter: { name: "frontlineutils", url: "http://twitter.com" },
53
+ youtube: { name: "frontlineutils", url: "https://youtube.com/user" },
54
+ linkedin: { name: "frontline-utilities", url: "https://linkedin.com/company" },
55
+ fusion: { name: "flutils", url: "https://frontlinefusion.com" }
57
56
  },
58
57
  layouts: {
59
- '404' => nil, #-> 404 Callback (needs improving big time) Use the following: '404' => <<-EOF redirect_to root_url, notice: "Hello" EOF
60
- '400' => nil, #-> layout for 400 error code (404 should only be used as response)
61
- '500' => 'exception'
58
+ "400" => nil, # => inherits from "ApplicationController" layout
59
+ "500" => "exception"
62
60
  },
63
61
  }
64
62
 
65
63
  ###########################################
66
64
 
67
65
  end
68
- end
66
+ end
@@ -0,0 +1,36 @@
1
+ module ExceptionHandler
2
+ class Engine < Rails::Engine
3
+
4
+ #########################################################
5
+ #########################################################
6
+
7
+ # => Wraps helpers in ExceptionHandler module
8
+ # => http://guides.rubyonrails.org/engines.html#inside-an-engine
9
+ # => http://stackoverflow.com/questions/31877839/accessing-helpers-from-the-parent-app-in-an-isolated-rails-engine
10
+ isolate_namespace ExceptionHandler
11
+
12
+ # => Tests
13
+ config.generators do |g|
14
+ g.test_framework :rspec
15
+ end
16
+
17
+ # => Assets
18
+ # => For Sprockets 4, had to include link_tree in exception_handler.css
19
+ config.assets.precompile << %w(exception_handler.css)
20
+
21
+ #########################################################
22
+ #########################################################
23
+
24
+ # => Hooks
25
+ # => This should be config.before_initialize but because ActiveRecord is not initialized, cannot check for table
26
+ initializer :exception_handler, before: "better_errors.configure_rails_initialization" do |app|
27
+ ExceptionHandler.config ||= ExceptionHandler::Config.new config.try(:exception_handler) # => Vars
28
+ app.config.exceptions_app = ->(env) { ExceptionHandler::ExceptionController.action(:show).call(env) } # => Rails
29
+ app.config.consider_all_requests_local = false if Rails.env.development? && ExceptionHandler.config.try(:dev) # => Dev
30
+ end
31
+
32
+ #########################################################
33
+ #########################################################
34
+
35
+ end
36
+ end
@@ -1,37 +1,55 @@
1
1
  ###########################################
2
2
 
3
3
  require 'rails/generators/active_record'
4
+ require 'exception_handler/exception' # => ATTRS constant (for attributes)
4
5
 
5
6
  ###########################################
6
7
 
7
- #Migration Generator (for adding errors table)
8
- #Ref: https://github.com/plataformatec/devise/blob/master/lib/generators/active_record/devise_generator.rb
8
+ # => Migration Generator (for adding errors table)
9
+ # => Ref: https://github.com/plataformatec/devise/blob/master/lib/generators/active_record/devise_generator.rb
9
10
 
10
11
  module ExceptionHandler
11
12
  class MigrationGenerator < ActiveRecord::Generators::Base
12
-
13
- #Name - from http://old.thoughtsincomputation.com/posts/cgfr3-part-3-adding-a-generator
13
+
14
+ # => Name - from http://old.thoughtsincomputation.com/posts/cgfr3-part-3-adding-a-generator
14
15
  argument :name, default: "migration"
15
16
 
16
- #Source of Migrations
17
+ # => Source of Migrations
17
18
  source_root File.expand_path("../../templates", __FILE__)
18
19
 
19
20
  ###########################################
20
21
 
21
- #Table Name - false = off, true = errors, value = value
22
- #Always outputs string for some reason...
22
+ # => Table Name - false = off, true = errors, value = value
23
+ # => Always outputs string for some reason...
23
24
  def table_name
24
25
  ExceptionHandler.config.db
25
26
  end
26
27
 
27
28
  ###########################################
28
29
 
29
- #Create
30
+ # => Create
30
31
  def create_errors_migration
31
- migration_template "migration.rb.erb", "db/migrate/create_errors.rb"
32
+ migration_template "migration.rb.erb", "db/migrate/create_#{table_name.to_s.gsub("_","")}.rb", migration_version: migration_version
33
+ end
34
+
35
+ ###########################################
36
+
37
+ # => From Devise
38
+ # => https://github.com/plataformatec/devise/blob/master/lib/generators/active_record/devise_generator.rb#L81
39
+
40
+ # => Rails 5?
41
+ def rails5?
42
+ Rails.version.start_with? '5'
43
+ end
44
+
45
+ # => Migration Version
46
+ def migration_version
47
+ if rails5?
48
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
49
+ end
32
50
  end
33
51
 
34
52
  ###########################################
35
53
 
36
54
  end
37
- end
55
+ end