exception_handler 0.7.7.0 → 0.8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +13 -3
  3. data/.rspec +3 -0
  4. data/.travis.yml +4 -2
  5. data/Gemfile +3 -0
  6. data/README.md +330 -124
  7. data/app/assets/stylesheets/exception_handler.css.erb +5 -0
  8. data/app/assets/stylesheets/styles/_base.css.erb +1 -8
  9. data/app/assets/stylesheets/styles/_exception.css.erb +2 -1
  10. data/app/controllers/exception_handler/exceptions_controller.rb +10 -3
  11. data/app/models/exception_handler/exception.rb +21 -20
  12. data/app/views/exception_handler/exceptions/show.html.erb +1 -1
  13. data/app/views/layouts/exception.html.erb +5 -0
  14. data/app/views/layouts/mailer.html.erb +5 -0
  15. data/app/views/layouts/mailer.text.erb +1 -0
  16. data/config/locales/exception_handler.en.yml +1 -1
  17. data/config/routes.rb +42 -0
  18. data/exception_handler.gemspec +9 -8
  19. data/lib/exception_handler.rb +1 -0
  20. data/lib/exception_handler/config.rb +109 -40
  21. data/lib/exception_handler/engine.rb +11 -3
  22. data/lib/exception_handler/version.rb +2 -2
  23. data/spec/controllers/controller_spec.rb +107 -0
  24. data/spec/dummy/.rspec +1 -0
  25. data/spec/dummy/.ruby-version +1 -0
  26. data/spec/dummy/Rakefile +6 -0
  27. data/spec/dummy/app/assets/config/manifest.js +3 -0
  28. data/spec/dummy/app/assets/images/.keep +0 -0
  29. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  30. data/spec/dummy/app/assets/javascripts/cable.js +13 -0
  31. data/spec/dummy/app/assets/javascripts/channels/.keep +0 -0
  32. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  33. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  34. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  35. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  36. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  37. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  38. data/spec/dummy/app/jobs/application_job.rb +2 -0
  39. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  40. data/spec/dummy/app/models/application_record.rb +3 -0
  41. data/spec/dummy/app/models/concerns/.keep +0 -0
  42. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  43. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  44. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  45. data/spec/dummy/bin/bundle +3 -0
  46. data/spec/dummy/bin/rails +4 -0
  47. data/spec/dummy/bin/rake +4 -0
  48. data/spec/dummy/bin/setup +36 -0
  49. data/spec/dummy/bin/update +31 -0
  50. data/spec/dummy/bin/yarn +11 -0
  51. data/spec/dummy/config.ru +5 -0
  52. data/spec/dummy/config/application.rb +18 -0
  53. data/spec/dummy/config/boot.rb +5 -0
  54. data/spec/dummy/config/cable.yml +10 -0
  55. data/spec/dummy/config/database.yml +25 -0
  56. data/spec/dummy/config/environment.rb +5 -0
  57. data/spec/dummy/config/environments/development.rb +61 -0
  58. data/spec/dummy/config/environments/production.rb +94 -0
  59. data/spec/dummy/config/environments/test.rb +46 -0
  60. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  61. data/spec/dummy/config/initializers/assets.rb +14 -0
  62. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  63. data/spec/dummy/config/initializers/content_security_policy.rb +25 -0
  64. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  65. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  66. data/spec/dummy/config/initializers/inflections.rb +16 -0
  67. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  68. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  69. data/spec/dummy/config/locales/en.yml +33 -0
  70. data/spec/dummy/config/puma.rb +34 -0
  71. data/spec/dummy/config/routes.rb +3 -0
  72. data/spec/dummy/config/storage.yml +34 -0
  73. data/spec/dummy/lib/assets/.keep +0 -0
  74. data/spec/dummy/log/.keep +0 -0
  75. data/spec/dummy/package.json +5 -0
  76. data/spec/dummy/public/404.html +67 -0
  77. data/spec/dummy/public/422.html +67 -0
  78. data/spec/dummy/public/500.html +66 -0
  79. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  80. data/spec/dummy/public/apple-touch-icon.png +0 -0
  81. data/spec/dummy/public/favicon.ico +0 -0
  82. data/spec/dummy/spec/rails_helper.rb +57 -0
  83. data/spec/dummy/spec/spec_helper.rb +100 -0
  84. data/spec/dummy/storage/.keep +0 -0
  85. data/spec/features/asset_spec.rb +61 -0
  86. data/spec/features/config_spec.rb +51 -0
  87. data/spec/features/engine_spec.rb +180 -0
  88. data/spec/routing/routing_spec.rb +85 -0
  89. data/spec/spec_helper.rb +93 -0
  90. data/spec/views/views_spec.rb +29 -0
  91. metadata +79 -6
  92. data/app/assets/images/exception_handler/bg.jpg +0 -0
  93. data/app/assets/images/exception_handler/bg_overlay.png +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 148c46f79b5ee16ca3c48ec3e9bffc41624ec964
4
- data.tar.gz: 25c4c163fbbf6fbc0e11622150b9384f853f3c23
2
+ SHA256:
3
+ metadata.gz: 49e2fc9996c4c5b2d6f795f5e08214d8fcb6d8228b735416903da5bd0e149ac6
4
+ data.tar.gz: 7c08ef59fa0f7766c07ce6da3c6a92d90dd543ad4c7bb1e3884289bd309e309d
5
5
  SHA512:
6
- metadata.gz: 592424a51d78607fd8ca707e573f98fe5586ea55920ca39fcc598228cece073f2c25002dd57ee09b17233096a78bde8ece09f165309d99d071c44e8dc654a6d7
7
- data.tar.gz: d65c120bf893e025fa1f68808a2feb1d403b7f3e036088e0ebb253008c67861f4e50f5e24ac12b3bd812e910cb113ec4b1cf37ae9af52ff9285196e5937a373f
6
+ metadata.gz: 937f0e527726d0c0af814b16b9a276290dad5181eb482280d9ed9230bde06d8094a88ef9e8d5abe27656c86c593b20a7ffcde427c7d0782cd55ba7d7b3d1be2c
7
+ data.tar.gz: 1ca6e353d9a05b023bcc2ca23321135cd7215b6a7be448d69979b698b309033a3c73d435678313f584fb8caac6e7eb48323ab2d7f73bcf62235a03df78ffb228
data/.gitignore CHANGED
@@ -21,17 +21,27 @@ tmp
21
21
  *.a
22
22
  mkmf.log
23
23
  *.tmp
24
+ .rspec_status
25
+
26
+ ##########################################################
27
+ ##########################################################
28
+
29
+ # http://stackoverflow.com/questions/8865848/comments-in-gitignore
30
+
31
+ ##########################################################
32
+ ##########################################################
24
33
 
25
34
  # Desktop INI (Windows)
26
35
  desktop.ini
27
36
 
37
+ # Readme Source (PSD's)
38
+ readme/source
39
+
28
40
  # Git BFG
29
41
  .git.bfg-report
30
42
  .git.bfg-report/2017-06-29/07-53-00
31
43
 
32
- # http://stackoverflow.com/questions/8865848/comments-in-gitignore
33
- # https://gist.github.com/danielpcox/4636520
34
-
44
+ # Specs
35
45
  log/*.log
36
46
  pkg/
37
47
  spec/dummy/db/*.sqlite3
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format progress
2
+ --color
3
+ --require spec_helper
@@ -1,5 +1,7 @@
1
+ language: ruby
1
2
  rvm:
2
3
  - 2.2.4
3
- - 2.3.2
4
- - 2.4.0
4
+ - 2.3.7
5
+ - 2.4.4
6
+ - 2.5.1
5
7
  - ruby-head
data/Gemfile CHANGED
@@ -10,4 +10,7 @@ group :test do
10
10
  gem 'coveralls', require: false
11
11
  end
12
12
 
13
+ # => Required for Windows
14
+ gem 'tzinfo-data' if Gem.win_platform? # => TZInfo For Windows
15
+
13
16
  ###########################################
data/README.md CHANGED
@@ -1,7 +1,20 @@
1
+ <p align="center">
2
+ <strong>💣 README Currently Being Updated 💣 - Gem Incorporated into 💀 <a href="https://www.vpsdeploy.com" title="Custom VPS Deployment For Rails"><u>VPSDeploy.com - VPS Deployment Solution</u></a> 💀 -<br/><code>Custom Programming Tutorials</code> + <code>Deployment Infrastructure</code> For Cloud VPS Providers...</strong>
3
+ </p>
4
+ <hr />
5
+
1
6
  ![Exception Handler](readme/title.jpg "Exception Handler Logo")
2
7
 
3
8
  <p align="center">
4
- <font size="4"><strong>Custom 404 & 500 production error pages for Rails 4 & 5.</font></strong>
9
+ <img src="./readme/dev.png" /><br />
10
+ </p>
11
+
12
+ <p align="center">
13
+ <img src="/readme/titles/initial.png" width="90%" />
14
+ </p>
15
+
16
+ <p align="center">
17
+ <strong>➡️ <code>ExceptionHandler</code> is a <a href="https://medium.com/ruby-on-rails-web-application-development/custom-400-500-error-pages-in-ruby-on-rails-exception-handler-3a04975e4677"><code>Custom Error Pages Gem</code></a> For Ruby on Rails ⬅️</strong> - With <strong>160,000+ downloads</strong>, it is one of the most <br /> <strong>popular</strong>, <strong>robust</strong> & <strong>extensible</strong> exceptions management gems for <strong><a href="https://rubygems.org/gems/exception_handler">Ruby on Rails 4 & 5+</a></strong>...
5
18
  </p>
6
19
 
7
20
  <p align="center">
@@ -14,132 +27,227 @@
14
27
  </p>
15
28
 
16
29
  <p align="center">
17
- <strong><a href="#install">Install</a></strong> → <strong><a href="#config">Setup</a></strong> <strong><a href="#support">Support</a></strong>
30
+ <img src="readme/branded/1.jpg" width="425" title="Fully Branded Error Pages" />
31
+ <img src="readme/branded/2.jpg" width="425" title="Fully Branded Error Pages" />
18
32
  </p>
19
33
 
20
- ---
21
-
22
34
  <p align="center">
23
- <img src="readme/version.jpg" /><br/>
35
+ <b>Version <a href="https://github.com/richpeck/exception_handler/releases/tag/v0.8.0.0">🏹 <code>0.8.0.0</code> 🏹</a> has now introduced a number of <b>⭐️ KEY UPGRADES ⭐️</b> including...</b> <br /> 🚧 <strong><A href="#config">New Config Settings</a></strong> 🚧 ▪️ <strong>💻 <strong><A href="#views">Custom Views Options</a></strong> 💻</strong> ▪️ <strong>💬 <a href="#locales"><code>4xx</code>/<code>5xx</code> Locales</a> 💬</strong>...
24
36
  </p>
25
37
 
26
38
  <p align="center">
27
- <img src="readme/check.png" height="22" title="Fully Responsive" align="absmiddle" />&nbsp; <strong>Responsive</strong> &nbsp;
28
- <img src="readme/check.png" height="22" title="Branded Error Pages" align="absmiddle" />&nbsp; <strong>Branded Error Pages</strong> &nbsp;
29
- <img src="readme/check.png" height="22" title="Middleware Exception Handling" align="absmiddle" />&nbsp; <strong>Middleware Exception Handling</strong> &nbsp;
30
- <img src="readme/check.png" height="22" title="Keep Users Informed" align="absmiddle" />&nbsp; <strong>Fully Customizable</strong> &nbsp;
39
+ <img src="readme/branded/1.jpg" width="425" title="Fully Branded Error Pages" /> <img src="readme/branded/2.jpg" width="425" title="Fully Branded Error Pages" />
40
+ <img src="readme/branded/3.jpg" width="425" title="Fully Branded Error Pages" /> <img src="readme/branded/4.jpg" width="425" title="Fully Branded Error Pages" />
31
41
  </p>
32
42
 
33
43
  <p align="center">
34
- <img src="readme/branded/1.jpg" width="425" title="Fully Branded Error Pages" /> <img src="readme/branded/2.jpg" width="425" title="Fully Branded Error Pages" />
35
- <img src="readme/branded/3.jpg" width="425" title="Fully Branded Error Pages" /> <img src="readme/branded/4.jpg" width="425" title="Fully Branded Error Pages" />
44
+ <strong>
45
+ ⚠️ Tutorial shows how it works ⚠️
46
+ <br /><a href="mailto: rpeck@frontlineutilities.co.uk" title="rpeck@fl.co.uk">✉️ Support Email ✉️</a>
47
+ </strong>
36
48
  </p>
37
49
 
38
- ---
50
+ <!-- Navigation -->
51
+ <div id="navigation">
52
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
53
+ <p align="center">
54
+ <b>⌚️ <a href="#introduction">Introduction</a> ⌚️</b> ❙ <strong>✔️ <a href="#installation">Installation</a> ✔️</strong> ❙ <strong>🔨 <a href="#setup">Setup</a> 🔨</strong> ❙ <strong>☎️ <a href="#support">Support</a> ☎️</strong> ❙ <strong>⭐ <a href="#changelog">Changelog</a> ⭐</strong>
55
+ </p>
56
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
57
+ </div>
39
58
 
59
+ <!-- Version -->
40
60
  <p align="center">
41
- <img src="readme/rails.jpg" title="Version 0.7.5 Released Early 2017" />
61
+ <img src="./readme/version.jpg" />
42
62
  </p>
43
63
 
44
- ---
45
-
46
64
  <p align="center">
47
- <img src="readme/titles/rails5.png" title="Fully Rails 5 Compatible" width="625" />
65
+ <img src="readme/check.png" height="22" title="Fully Responsive" align="absmiddle" />&nbsp; <strong>Responsive</strong> &nbsp;
66
+ <img src="readme/check.png" height="22" title="Branded Error Pages" align="absmiddle" />&nbsp; <strong>Branded Error Pages</strong> &nbsp;
67
+ <img src="readme/check.png" height="22" title="Middleware Exception Handling" align="absmiddle" />&nbsp; <strong>Middleware Exception Handling</strong> &nbsp;
68
+ <img src="readme/check.png" height="22" title="Keep Users Informed" align="absmiddle" />&nbsp; <strong>Fully Customizable</strong> &nbsp;
48
69
  </p>
49
70
 
50
71
  <p align="center">
51
- <img src="readme/check_02.png" height="22" title="New Controller" align="absmiddle" />&nbsp; <strong align="absmiddle">New Controller</strong> &nbsp;
52
- <img src="readme/check_02.png" height="22" title="New Middleware" align="absmiddle" />&nbsp; <strong align="absmiddle">New Middleware</strong> &nbsp;
53
- <img src="readme/check_02.png" height="22" title="Full Test Suite" align="absmiddle" />&nbsp; <strong align="absmiddle">Full Test Suite</strong> &nbsp;
54
- <img src="readme/check_02.png" height="22" title="Rails 4 & 5 Compatible" align="absmiddle" />&nbsp; <strong align="absmiddle">Fully Rails 4 & 5 Compatible</strong> &nbsp;
72
+ <img src="readme/branded/1.jpg" width="425" title="Fully Branded Error Pages" /> <img src="readme/branded/2.jpg" width="425" title="Fully Branded Error Pages" />
73
+ <img src="readme/branded/3.jpg" width="425" title="Fully Branded Error Pages" /> <img src="readme/branded/4.jpg" width="425" title="Fully Branded Error Pages" />
55
74
  </p>
56
75
 
57
- Brand new `controller` & `middleware` have made **`ExceptionHandler`** even more powerful & efficient. Now you can use `ExceptionHandler` with a [single click](#install) → **plug and play** custom exception pages:
76
+ <!-- Introduction -->
77
+ <div id="introduction">
78
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
79
+ <p>
80
+ <h3>⌚️ Introduction ⌚️</h3>
81
+ </p>
82
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
83
+ </div>
84
+
85
+ ➡️ [**`ExceptionHandler`**](https://rubygems.org/gems/exception_handler) ⬅️ was designed to replace Rails' error pages ([`400.html`, `422.html`, `500.html`](https://github.com/rails/rails/tree/ef0b05e78fb0b928c7ef48d3c365dc849af50305/railties/lib/rails/generators/rails/app/templates/public)) with dynamic views...
58
86
 
59
87
  <p align="center">
60
- <br />
61
- <img src="readme/400.png" title="400 Errors" width="430" />
62
- <img src="readme/500.png" title="500 Errors" width="430" />
88
+ <img src="./readme/http_codes.png" />
63
89
  </p>
64
90
 
65
- <p align="center">For over 3 years, <strong>ExceptionHandler</strong> has provided production-level <strong>Rails</strong> exception handling for <strong>4xx</strong> and <strong>5xx</strong> errors:</p>
91
+ The gem inserts a custom [ `controller`](app/controllers/exception_handler/exceptions_controller.rb) into [`exceptions_app`](http://guides.rubyonrails.org/configuring.html#rails-general-configuration), allowing us to render custom HTML for erroneous requests.
66
92
 
67
- ![HTTP Error Codes][http_codes]
93
+ The controller uses a *single* method/view to build a response to errors. This view remains the same for *every* exception; the ONLY change is the *[layout](/app/views/layouts/exception.html.erb)* - depending on the HTTP response being returned (`4xx`/`5xx`).
68
94
 
69
- Since **browsers only read `4xx` & `5xx` error codes**, all Rails exceptions have to be inferred. Thus, `ExceptionHandler` simply has to manage how the `4xx` / `5xx` errors are passed to the browser.
95
+ The beauty lies in the *simplicity* through which this is achieved rather than having many different elements, its SOLE focus is to provide different HTML responses via differing *layouts*. `ExceptionHandler` does this within the scope of [`ActionView`](http://guides.rubyonrails.org/action_view_overview.html), allowing for the use of `views`, `helpers` and `data` from the database.
70
96
 
71
- Unlike other gems, **`ExceptionHandler` uses a custom [`controller`](app/controllers/exception_handler/exceptions_controller.rb) to build an [`@exception`](app/models/exception_handler/exception.rb) object**. This allows us to save the exception, email it or do anything else we may need. The gem has already been a massive success and we continue to actively maintain it.
97
+ Gem works 100% out of the box in `production`, and has the option to be called in [`dev`](#dev) if necessary.
72
98
 
73
- Now you can try for yourself ...
99
+ --
74
100
 
101
+ ### 📑 HTTP
75
102
 
76
- ----
103
+ The most important thing to understand is that *it doesn't matter* which errors Ruby/Rails raises - they *all* need to be wrapped in a [valid HTTP response](https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html). Due to the nature of HTTP, you only need to facilitate responses for [`4xx`](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors) - [`5xx`](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_errors).
77
104
 
78
- <p align="center">
79
- <br />
80
- <img src="readme/titles/middleware.png" title="Middleware-Powered Exceptions" width="400" />
81
- </p>
105
+ This means that all you're really doing is taking "Ruby" errors and giving them an appropriate [HTTP status code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) & [message body](https://en.wikipedia.org/wiki/HTTP_message_body) (HTML). Rails handles the process for you - the *only* thing we need to worry about is how the HTML is generated.
82
106
 
83
- The secret lies in [**`config.exceptions_app`**][exception_app] ↴
107
+ What confuses most is the way in which Rails does this. The process is handled by [`ActionDispatch::ShowExceptions`](https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L44) - which builds a new response out of the one passed to it by the exception generator. Through this process, it calls whichever class is present in [`exceptions_app`](http://guides.rubyonrails.org/configuring.html#rails-general-configuration)...
84
108
 
85
- > **`config.exceptions_app`** sets the exceptions application invoked by the **`ShowException`** middleware when an exception happens. Defaults to **`ActionDispatch::PublicExceptions.new(Rails.public_path)`**
109
+ # show_exceptions.rb
110
+ def render_exception(request, exception)
111
+ backtrace_cleaner = request.get_header "action_dispatch.backtrace_cleaner"
112
+ wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)
113
+ status = wrapper.status_code
114
+ request.set_header "action_dispatch.exception", wrapper.exception
115
+ request.set_header "action_dispatch.original_path", request.path_info
116
+ request.path_info = "/#{status}"
117
+ response = @exceptions_app.call(request.env) #-> this is where the HTML is generated
118
+ response[1]["X-Cascade"] == "pass" ? pass_response(status) : response
119
+ rescue Exception => failsafe_error
120
+ $stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}"
121
+ FAILSAFE_RESPONSE
122
+ end
86
123
 
87
- ![Exceptions handled by the ActiveDispatch::ShowExceptions Middleware][middleware]
124
+ In other words, what a user *sees* has very little to do with the fact Rails experienced an error. `ExceptionHandler` doesn't change this behaviour - it simply adds our own controller/views setup to provide the HTML...
88
125
 
89
- Each time an exception is raised, [`ShowExceptions`][show_exception] takes the request and forwards it to `config.exceptions_app`. This is expected to return a response - allowing us to inject a [`controller`](app/controllers/exception_handler/exceptions_controller.rb):
126
+ <p align="center">
127
+ <img src="./readme/middleware.jpg" />
128
+ </p>
90
129
 
91
- ![config.exceptions_app - The key to all Rails exceptions][exceptions_app]
130
+ To better explain, there are **<a href="https://tzamtzis.gr/2017/digital-analytics/http-status-codes/">5️⃣ types of HTTP status code</a>** - [`10x`][10x], [`20x`][20x], [`30x`][30x], [`40x`][40x], & [`50x`][50x].
92
131
 
93
- Because our callback maintains the request, we are able to do whatever we need before serving a response. This is a **major** advantage over the "default" (routes). The routes invokes Rails twice and does not persist the request.
132
+ Each does its own thing, but what's important is they *ALL* describe "responses" that your web browser will receive for HTTP requests. The only *erroneous* status codes are `4xx` (client error) or `5xx` (server error)...
94
133
 
95
- **`ExceptionHandler` is the only gem to provide middleware-powered exception handling.** It populates our custom `view` with details, giving us the ability to **maintain branding** when exceptions are raised:
134
+ <p align="center">
135
+ <img src="./readme/HTTP.png" />
136
+ </p>
96
137
 
97
- ![Exceptions handled by the ActiveDispatch::ShowExceptions Middleware][middleware]
138
+ The point is that when you're dealing with "errors" online, you're *actually* dealing with erroneous **HTTP STATUS CODES**. The response delivered with these codes is *ALWAYS* going to remain the same; difference lying in how they're built (on the server).
98
139
 
99
- **`ExceptionHandler` is the most EFFECTIVE and EFFICIENT gem to handle exceptions in Rails**.
140
+ By default, `NGinx` + `Apache` use "static" HTML pages to show the errors - if we're using Rails, we have the ability to create *our own* pages. This is exactly what our gem has been designed to do.
100
141
 
101
- Once invoked, its `model`, `controller` and `views` work together to serve the best responses to Rails errors ...
142
+ **`ExceptionHandler`** provides Rails with the ability to serve ***dynamic*** exception pages, built with **your *own*** layouts/views. By overriding the <a href="http://guides.rubyonrails.org/configuring.html#rails-general-configuration">`exceptions_app`</a> hook, it provides a custom `controller`, `model` and `views` to display custom error pages.
102
143
 
103
- ----------
104
-
105
- <p align="center" id="install">
106
- <br />
107
- <img src="readme/titles/install.png" title="1 Click Install for ExceptionHandler 0.7.0 on Rails 5" width="400" />
108
- <br />
109
- <strong>Custom Rails Error Pages - ZERO configuration needed:</strong>
110
- <br />
111
- </p>
144
+ The system is 100% compatible with Rails 4 & 5 and has already been downloaded **180,000+** times...
112
145
 
113
146
  <p align="center">
114
- <a href="http://rubygems.org/gems/exception_handler"><img src="readme/gem.jpg" /></a> <a href="http://rubygems.org/gems/exception_handler"><img src="readme/gemfile.jpg" /></a>
147
+ <img src="readme/branded/1.jpg" width="425" title="Fully Branded Error Pages" /> <img src="readme/branded/2.jpg" width="425" title="Fully Branded Error Pages" />
148
+ <img src="readme/branded/3.jpg" width="425" title="Fully Branded Error Pages" /> <img src="readme/branded/4.jpg" width="425" title="Fully Branded Error Pages" />
115
149
  </p>
116
150
 
151
+ <!-- Setup -->
152
+ <div id="setup">
153
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
154
+ <h3 align="center">🔨 Setup 🔨</h3>
155
+ <p align="center">-- <br />The <i>most</i> important thing to appreciate about the gem is that it's designed to be <b><em>completely</em> unobtrusive</b>.</p>
156
+ <p align="center">This means that if you're looking at using it, </p>
157
+ <p align="center"><img src="./readme/dev.png" /></p>
158
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
159
+ <p align="center">
160
+ <a href="#config"><img src="readme/titles/icons/config.png" alt="Configuration Options" align="absmiddle" height="24" /> Config</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dev" title="Dev Mode"><img src="readme/titles/icons/dev.png" alt="Dev" align="absmiddle" height="24" /> Dev</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#database"><img src="readme/titles/icons/database.png" alt="Database" align="absmiddle" height="24" /> Database</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#email"><img src="readme/titles/icons/email.png" alt="Email" align="absmiddle" height="24" /> Email</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#views"><img src="readme/titles/icons/views.png" alt="Views" align="absmiddle" height="24" /> Views</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#locales"><img src="readme/titles/icons/locales.png" alt="Locales" align="absmiddle" height="20" /> Locales</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#custom-exceptions"><img src="readme/titles/icons/custom.png" alt="Custom Exceptions" align="absmiddle" height="18" /> Custom Exceptions</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#generators"><img src="readme/titles/icons/generators.png" alt="Generators" align="absmiddle" height="24" /> Generators</a>
161
+ </p>
162
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
163
+ </div>
117
164
 
118
- <p align="center">
119
- You can install it from the <strong>CLI</strong> or <strong>Gemfile</strong> - it will AUTOMATICALLY run in <strong>production</strong>.
120
- <br />
121
- <strong>↓ To run in development, use <a href="#dev-mode">dev mode</a> ↓</strong>
122
- </p>
165
+ <!-- Config -->
166
+ <p id="config">
167
+ <h4>🚧 Config 🚧</h4>
168
+ </p>
123
169
 
124
- ---
170
+ **The ONLY thing you need to configure `ExceptionHandler` is the [`config`](https://github.com/richpeck/exception_handler/blob/master/lib/exception_handler/config.rb)**.
125
171
 
126
- <p align="center">
127
- If you want to set it up your way, you can use these features...
128
- </p>
172
+ Whilst the gem **works out of the box** (without any configuration), if you want to manage the [`layouts`](#layouts), [`email`](#email), [`dev`](#dev) or the [`database`](#db), you'll need to set the appropriate values in the config hash ([invoked at init](https://github.com/richpeck/exception_handler/blob/master/lib/exception_handler/engine.rb#L44)).
129
173
 
130
- <p align="center">
131
- <a href="#config"><img src="readme/titles/icons/config.png" alt="Cinfiguration Options" align="absmiddle" height="24" /> Config</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dev-mode" title="Dev Mode"><img src="readme/titles/icons/dev.png" alt="Dev" align="absmiddle" height="24" /> Dev</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#database"><img src="readme/titles/icons/database.png" alt="Database" align="absmiddle" height="24" /> Database</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#email"><img src="readme/titles/icons/email.png" alt="Email" align="absmiddle" height="24" /> Email</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#views"><img src="readme/titles/icons/views.png" alt="Views" align="absmiddle" height="24" /> Views</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#locales"><img src="readme/titles/icons/locales.png" alt="Locales" align="absmiddle" height="20" /> Locales</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#custom-exceptions"><img src="readme/titles/icons/custom.png" alt="Custom Exceptions" align="absmiddle" height="18" /> Custom Exceptions</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#generators"><img src="readme/titles/icons/generators.png" alt="Generators" align="absmiddle" height="24" /> Generators</a>
132
- </p>
174
+ This can be done in `config/application.rb` or `config/environments/[env].rb` ↴
133
175
 
134
- ----
176
+ ```
177
+ # config/application.rb
135
178
 
136
- ## Config
179
+ module YourApp
180
+ class Application < Rails::Application
137
181
 
138
- **From [`0.4.7`](https://github.com/richpeck/exception_handler/releases/tag/0.4.6), `ExceptionHandler` manages its [config](lib/exception_handler/config.rb#L45) from the central Rails `config` hash:**
182
+ # => This is an example of ALL available config options
183
+ # => You're able to see exactly how it works here:
184
+ # => https://github.com/richpeck/exception_handler/blob/master/lib/exception_handler/config.rb
139
185
 
140
- [![config][config]](lib/exception_handler/config.rb#L45)
186
+ # => Config hash (no initializer required)
187
+ config.exception_handler = {
188
+ dev: nil, # allows you to turn ExceptionHandler "on" in development
189
+ db: nil, # allocates a "table name" into which exceptions are saved (defaults to nil)
190
+ email: nil, # sends exception emails to a listed email (string // "you@email.com")
191
+
192
+ # On default 5xx error page, social media links included
193
+ social: {
194
+ facebook: nil, # Facebook page name
195
+ twitter: nil, # Twitter handle
196
+ youtube: nil, # Youtube channel name / ID
197
+ linkedin: nil, # LinkedIn name
198
+ fusion: nil # FL Fusion handle
199
+ },
200
+
201
+ # This is an entirely NEW structure for the "layouts" area
202
+ # You're able to define layouts, notifications etc ↴
203
+
204
+ # All keys interpolated as strings, so you can use symbols, strings or integers where necessary
205
+ exceptions: {
206
+
207
+ :all => {
208
+ layout: "exception", # define layout
209
+ notification: true, # (false by default)
210
+ deliver: #something here to control the type of response
211
+ },
212
+ :4xx => {
213
+ layout: nil, # define layout
214
+ notification: true, # (false by default)
215
+ deliver: #something here to control the type of response
216
+ },
217
+ :5xx => {
218
+ layout: "exception", # define layout
219
+ notification: true, # (false by default)
220
+ deliver: #something here to control the type of response
221
+ },
222
+ 500 => {
223
+ layout: "exception", # define layout
224
+ notification: true, # (false by default)
225
+ deliver: #something here to control the type of response
226
+ },
227
+
228
+ # This is the old structure
229
+ # Still works but will be deprecated in future versions
230
+
231
+ 501 => "exception",
232
+ 502 => "exception",
233
+ 503 => "exception",
234
+ 504 => "exception",
235
+ 505 => "exception",
236
+ 507 => "exception",
237
+ 510 => "exception"
238
+
239
+ }
240
+ }
241
+
242
+ end
243
+ end
244
+ ```
245
+
246
+ For a full retinue of the available options, you'll be best looking at the [`config`](https://github.com/richpeck/exception_handler/blob/master/lib/exception_handler/config.rb) file itself.
141
247
 
142
- If you're using an [`engine`](http://guides.rubyonrails.org/engines.html), you don't need to use an `initializer`:
248
+ --
249
+
250
+ If using an [`engine`](http://guides.rubyonrails.org/engines.html), **DON'T need an `initializer`**:
143
251
 
144
252
  # lib/engine.rb
145
253
  module YourModule
@@ -148,45 +256,58 @@ If you're using an [`engine`](http://guides.rubyonrails.org/engines.html), you d
148
256
  # => ExceptionHandler
149
257
  # => Works in and out of an initializer
150
258
  config.exception_handler = {
151
- dev: false,
152
- db: true
259
+ dev: nil, # => this will not load the gem in development
260
+ db: true # => this will use the :errors table to store exceptions
153
261
  }
154
262
  end
155
263
 
156
264
  end
157
265
 
158
- You only need to provide the inputs you want, for example:
266
+ The best thing about using a `config` options block is that you are able to only define the options that you require. This means that if you have particular options you *only* wish to run in `staging`, or have single options for `production` etc...
159
267
 
160
- # config/application.rb
161
- config.exception_handler = { dev: true }
268
+ ---
162
269
 
163
- # config/environments/production.rb
164
- config.exception_handler = { social: { fusion: "flutils" }}
270
+ <p id="dev">
271
+ <h4>💻 Dev 💻</h4>
272
+ </p>
165
273
 
166
- ----
274
+ As explained, `ExceptionHandler` does not work in `development` mode by default. This is because it overrides the `exceptions_app` middleware hook - which is only invoked in `production` or `staging`...
275
+
276
+ <p align="center">
277
+ <img src="./readme/dev.png" />
278
+ </p>
167
279
 
168
- ## Dev Mode
280
+ To get it working in `development`, you need to override the [`config.consider_all_requests_local`](http://guides.rubyonrails.org/configuring.html#rails-general-configuration) setting (a standard component of Rails) - setting it to "false" ↴
281
+
282
+ <p align="center">
283
+ <img src="./readme/local_requests.jpg" />
284
+ </p>
169
285
 
170
- **To enable `ExceptionHandler` in dev, enable the [`dev`](lib/exception_handler/config.rb#L38) option:**
286
+ This is normally done by changing the setting in your Rails config files. However, to make the process simpler for `ExceptionHandler`- we've added a `dev` option which allows you to override the hook through the context of the gem...
171
287
 
172
- ![Dev][dev_mode]
288
+ ```
289
+ # config/application.rb
290
+ config.exception_handler = { dev: true }
291
+ ```
173
292
 
174
293
  This disables [`config.consider_all_requests_local`](http://guides.rubyonrails.org/configuring.html#rails-general-configuration), making Rails behave as it would in production:
175
294
 
176
295
  ![Dev][dev_img]
177
296
 
297
+ Obviously, this has other connotations including the likes of making your requests go through your production server etc. For this reason, it's *STRONGLY* recommended you only use the `dev` option to test your layouts etc.
298
+
178
299
  ----
179
300
 
180
- ## Database
301
+ <p id="database">
302
+ <h4>💾 Database 💾</h4>
303
+ </p>
181
304
 
182
- **We also have `ActiveRecord` integration.**
305
+ If you want to save exceptions to your database, you will need to migrate a new
183
306
 
184
- If you want to save your exceptions to `db`, you need to enable the `db` config option:
185
-
186
- # config/application.rb
187
- config.exception_handler = {
188
- db: true
189
- }
307
+ ```
308
+ # config/application.rb
309
+ config.exception_handler = { db: true }
310
+ ```
190
311
 
191
312
  This enables `ActiveRecord::Base` on the [`Exception`](app/models/exception_handler/exception.rb) class, allowing us to save to the database.
192
313
 
@@ -196,7 +317,9 @@ To do this, once you've enabled the option, run `rails db:migrate` from your con
196
317
 
197
318
  ---
198
319
 
199
- ## Email
320
+ <p id="email">
321
+ <h4>✉️ Email ✉️</h4>
322
+ </p>
200
323
 
201
324
  **`ExceptionHandler` also now sends email notifications.**
202
325
 
@@ -213,22 +336,43 @@ If you want to receive emails whenever your application raises an error, you can
213
336
 
214
337
  ---
215
338
 
216
- ## Views
339
+ <p id="views">
340
+ <h4>👓 Views 👓</h4>
341
+ </p>
342
+
343
+ The **views** system in `ExceptionHandler` is modular.
344
+
345
+ What *most* people want out of the view is to change the way it ***looks***. This can be done without changing the exception "view" itself...
346
+
347
+ <p align="center">
348
+ <img src="./readme/dev.png" />
349
+ </p>
350
+
351
+ To better explain, if [`ExceptionsController`](https://github.com/richpeck/exception_handler/blob/0.8/app/controllers/exception_handler/exceptions_controller.rb) is invoked (by `exceptions_app`), it has **ONE** method ([`show`](https://github.com/richpeck/exception_handler/blob/0.8/app/controllers/exception_handler/exceptions_controller.rb#L42)). This method calls the [`show` view](https://github.com/richpeck/exception_handler/blob/0.8/app/views/exception_handler/exceptions/show.html.erb), which is *entirely* dependent on the locales for content & the layout for the look.
352
+
353
+ This means that if you wish to change how the view "looks" - you're *either* going to want to change your *layouts* or the [*locales*](#locales). There is NO reason to change the `show` view itself - it's succinct and entirely modular. Whilst you're definitely at liberty to change it, you'll just be making the issue more complicated than it needs to be.
354
+
355
+ -
217
356
 
218
- **From [`0.7.0`](#070), we overhauled the view system:**
357
+ If you wish to change the "layout" / "look", there are **two** options...
219
358
 
220
- ![View][view_img]
359
+ * Firstly, you can create your own layout. This is done by changing the
221
360
 
222
- [Wiew](app/views/exception_handler/exceptions/show.html.erb) is modular - `@exception` populated with [`locales`](#locales).
361
+ * Secondly,
223
362
 
224
363
  ---
225
364
 
226
- ## Locales
365
+ <p id="locales">
366
+ <h4>💬 Locales 💬</h4>
367
+ </p>
227
368
 
228
- **[`0.7.5`](https://github.com/richpeck/exception_handler/releases/tag/0.7.5) introduced [locales](config/locales/exception_handler.yml) ...**
369
+ Locales are used to denote interchangeable text (for different languages).
370
+
371
+ We've used it for a different purpose - to provide text for our "show" view. The beauty of this is that 1) It's entirely modular & 2) It's extensible (we are able to use as many locales as required)...
229
372
 
230
373
  [[ locales ]]
231
374
 
375
+
232
376
  The `ExceptionHandler` view is populated by [`@exception.description`](app/models/exception_handler/exception.rb#L121), which pulls from the `locales`.
233
377
 
234
378
  If you want custom messages, you need the following. The key is defined by the HTTP [`status_code`](https://github.com/rack/rack/blob/1.5.2/lib/rack/utils.rb#L544)
@@ -244,13 +388,13 @@ You get access to `%{message}` and `%{status}`, both inferring from `@exception`
244
388
 
245
389
  ---
246
390
 
247
- ## Layout
248
-
249
- **The `layout` has also been improved ↴**
391
+ <p id="layouts">
392
+ <h4>📋 Layouts 📋</h4>
393
+ </p>
250
394
 
251
395
  ![Layout][layout_img]
252
396
 
253
- We now assign layouts to the **status code** of the response:
397
+ If you want to change the various layouts, you need to use the [`config`](#config) to set them.
254
398
 
255
399
  ![Layout][layouts_img]
256
400
 
@@ -259,7 +403,9 @@ By default, `5xx` errors are shown with our [`exception` layout][layout] - this
259
403
  ---
260
404
 
261
405
 
262
- ## Custom Exceptions
406
+ <p id="custom-exceptions">
407
+ <h4>⛔️ Custom Exceptions ⛔️</h4>
408
+ </p>
263
409
 
264
410
  **Custom Exceptions also supported in [`0.7.5`](https://github.com/richpeck/exception_handler/releases/tag/0.7.5)**
265
411
 
@@ -276,7 +422,9 @@ Because `HTTP` can only process `4xx` / `5xx` errors, if `Rails` raises an excep
276
422
 
277
423
  ---
278
424
 
279
- ## Generators
425
+ <p id="generators">
426
+ <h4>💼 Generators 💼</h4>
427
+ </p>
280
428
 
281
429
  **You can generate `ExceptionHandler` into your own application.**
282
430
 
@@ -297,34 +445,79 @@ Each switch defines which folders you want (EG `-v views` will only copy `views`
297
445
 
298
446
  ---
299
447
 
300
- ### Migrations (deprecated)
448
+ <p id="migrations">
449
+ <h4>✔️ Migrations (deprecated) ✔️</h4>
450
+ </p>
451
+
452
+ **You *DON'T* need to generate a migration any more**.
301
453
 
302
- **From [`0.7.5`](https://github.com/richpeck/exception_handler/releases/tag/0.7.5), the `migration` generator has been removed in favour of our own [migration system](lib/exception_handler/engine.rb#L58)**
454
+ From [`0.7.5`](https://github.com/richpeck/exception_handler/releases/tag/0.7.5), the `migration` generator has been removed in favour of our own [migration system](lib/exception_handler/engine.rb#L58).
303
455
 
304
- You don't need to generate a migration any more.
456
+ The reason we did this was so not to pollute your migrations folder with a worthless file. Our migration doesn't need to be changed - we only have to get it into the database and the gem takes care of the rest...
305
457
 
306
- If you set the `db` option in config, run `rails db:migrate` and the migration will be run.
458
+ > If you set the `db` option in config, run `rails db:migrate` and the migration will be run.
307
459
 
308
460
  To rollback, use the following:
309
461
 
310
462
  rails db:migrate:down VERSION=000000
311
463
 
312
- > The drawback to this is that if you remove `ExceptionHandler` before you rollback the migration, it won't exist anymore. You can **only** fire the `rollback` when you have `ExceptionHandler` installed.
464
+ The drawback to this is that if you remove `ExceptionHandler` before you rollback the migration, it won't exist anymore. You can **only** fire the `rollback` when you have `ExceptionHandler` installed.
313
465
 
314
- ---
466
+ <!-- Support -->
467
+ <div id="support">
468
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
469
+ <h3>☎️ Support ☎️</h3>
470
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
471
+ </div>
315
472
 
316
- ## Support
473
+ <p align="center"><b>🚨 <em>Obviously</em>, if you've taken the time to use the gem, it makes sense to <a href="https://github.com/richpeck/exception_handler/issues">support</a> it 🚨!</b></p>
317
474
 
318
- [Issues](https://github.com/richpeck/exception_handler/issues)
475
+ The fastest way to get a **direct response** is via [email](mailto:rpeck@frontlineutilities.co.uk).
319
476
 
320
- ---
477
+ You're also welcome to access our [**Issues**](https://github.com/richpeck/exception_handler/issues) page to contact us directly. You could also use [**StackOverflow**](https://stackoverflow.com/questions/tagged/ruby-on-rails+exceptionhandler)...
478
+
479
+ - ⚠️ [**Issues**](https://github.com/richpeck/exception_handler/issues) ⚠️
480
+ - 🚩 [**StackOverflow**](https://stackoverflow.com/questions/tagged/ruby-on-rails+exceptionhandler) 🚩
481
+ - ✉️ [**Email**](mailto:rpeck@frontlineutilities.co.uk) ✉️
482
+ - ✏️ [**Medium**](https://medium.com/ruby-on-rails-web-application-development/custom-400-500-error-pages-in-ruby-on-rails-exception-handler-3a04975e4677) ✏️
483
+ - 🎥 [**YouTube**](https://www.youtube.com/channel/UC247lm76ECX1aSvVuhXxe6g) 🎥 ↴
484
+
485
+ <p align="center">
486
+ <a href="https://www.youtube.com/channel/UC247lm76ECX1aSvVuhXxe6g"><img src="./readme/youtube.png" /></a>
487
+ </p>
488
+
489
+ <!-- Changelog -->
490
+ <div id="changelog">
491
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
492
+ <h3>⭐ Changelog ⭐</h3>
493
+ <p align="center"><img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" /></p>
494
+ </div>
321
495
 
322
- ## Changelog
496
+ The most important thing to appreciate is...
323
497
 
324
- ### [0.7.5](https://github.com/richpeck/exception_handler/releases/tag/0.7.5)
498
+ <p align="center"><b>➡️ <code><a href="https://www.rubygems.org/gems/exception_handler">ExceptionHandler</a></code> is designed to provide <strong><A href="https://medium.com/ruby-on-rails-web-application-development/custom-400-500-error-pages-in-ruby-on-rails-exception-handler-3a04975e4677">custom error pages</a></strong> for Ruby on Rails. ⬅️</b></p>
499
+
500
+ <p>If you're looking at adding <em><b>extra</b></em> functionality (such as a debugger), you'll probably be better looking at the likes of <code><a href="https://rubygems.org/gems/better_errors">better_errors</a></code> or <code><a href="https://rubygems.org/gems/gaffe">gaffe</a></code>. Whilst we'll certainly look at adding - or integrating - other features (if they're requested), our core intention has always been to provide an exception handling stack that was both simple and customizable.</p>
501
+
502
+ --
503
+
504
+ What we've built so far...
505
+
506
+ ### 👻 [1.0.0.0](https://github.com/richpeck/exception_handler/releases/tag/v1.0.0.0)
507
+ - [ ] TBA
508
+
509
+ ### 🏹 [0.8.0.0](https://github.com/richpeck/exception_handler/releases/tag/v0.8.0.0)
510
+ - [x] [README](https://github.com/richpeck/exception_handler/issues/52) (focus on utility)
511
+ - [x] Introduction of `4xx`,`5xx`,`:all` for layouts config
512
+ - [x] Changed `layouts` to `exceptions` in config
513
+ - [x] Email improvement
514
+ - [x] Streamlined migration
515
+ - [x] Updated model
516
+
517
+ ### 👽 [0.7.7.0](https://github.com/richpeck/exception_handler/releases/tag/v0.7.7.0)
325
518
  - [x] [HTTP status layouts](#layouts)
326
519
 
327
- ### [0.7.0](https://github.com/richpeck/exception_handler/releases/tag/0.7.0)
520
+ ### 0.7.0.0
328
521
  - [x] Wildcard mime types
329
522
  - [x] [Custom exceptions](#custom_exceptions)
330
523
  - [x] Test suite integration
@@ -334,7 +527,7 @@ To rollback, use the following:
334
527
  - [x] New layout
335
528
  - [x] Readme / wiki overhaul
336
529
 
337
- ### [0.6.5](https://github.com/richpeck/exception_handler/releases/tag/0.6.5)
530
+ ### Ⓜ️ 0.6.5.0
338
531
  - [x] Streamlined interface
339
532
  - [x] ActiveRecord / Middleware overhaul
340
533
  - [x] Supports Sprockets 4+ ([`manifest.js`](http://eileencodes.com/posts/the-sprockets-4-manifest/))
@@ -342,7 +535,7 @@ To rollback, use the following:
342
535
  - [x] Asset overhaul & improvement
343
536
  - [x] Removed dependencies
344
537
 
345
- ### [0.5.0](https://github.com/richpeck/exception_handler/releases/tag/0.5.0)
538
+ ### ✔️ 0.5.0.0
346
539
  - [x] Locales
347
540
  - [x] Email notifications
348
541
  - [x] Full test suite
@@ -353,20 +546,23 @@ To rollback, use the following:
353
546
  - [x] Rails asset management improvement
354
547
  - [x] Reduced gem file size
355
548
 
356
- ### [0.4.7](https://github.com/richpeck/exception_handler/releases/tag/0.4.6)
549
+ ### 0.4.7.0
357
550
  - [x] New config system
358
551
  - [x] Fixed controller layout issues
359
552
  - [x] Streamlined middleware
360
553
  - [x] New layout & interface
361
554
 
362
- ----
555
+ <!-- Sep -->
556
+ <p align="center">
557
+ <img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" />
558
+ </p>
363
559
 
364
560
  [![404 + 500 Errors][banner]][rubygems]
365
561
 
366
562
  <p align="center">
367
- <strong><a href="#">ExceptionHandler</a> is now the leading custom error pages gem for Rails.</strong>
563
+ <strong><a href="https://rubygems.org/gems/exception_handler"><code>ExceptionHandler</code></a> is now the LEADING • custom error pages gem for Rails 4 & 5...</strong>
368
564
  <br />
369
- No other gem is as simple or effective at providing beautiful exception pages in production.
565
+ No other gem is as simple or effective at providing branded exception pages in production...
370
566
  </p>
371
567
 
372
568
  <p align="center">
@@ -379,12 +575,16 @@ To rollback, use the following:
379
575
  </p>
380
576
 
381
577
  <p align="center">
382
- <strong><a href="https://rubygems.org/gems/exception_handler">Download Here</a></strong>
578
+ <strong>➡️ <a href="https://rubygems.org/gems/exception_handler">Download & Info</a> ⬅️ </strong>
579
+ </p>
580
+
581
+ <!-- Sep -->
582
+ <p align="center">
583
+ <img src="https://cdn-images-1.medium.com/max/800/1*CKyKxRXLovcrUOB-s8_jCw.png" width="100%" />
383
584
  </p>
384
585
 
385
- ----------
586
+ :copyright: <a href="http://www.fl.co.uk" align="absmiddle" ><img src="readme/fl.jpg" height="22" align="absmiddle" /></a> <a href="http://stackoverflow.com/users/1143732/richard-peck?tab=profile" align="absmiddle" ><img src="https://avatars0.githubusercontent.com/u/1104431" height="22" align="absmiddle" /></a> <a href="https://github.com/joehilton" align="absmiddle" ><img src="https://avatars2.githubusercontent.com/u/5063592?s=460&v=4" height="22" align="absmiddle" /></a> <a href="https://github.com/toymachiner62" align="absmiddle" ><img src="https://avatars3.githubusercontent.com/u/485782" height="22" align="absmiddle" /></a> <a href="https://github.com/andrewclink" align="absmiddle" ><img src="https://avatars0.githubusercontent.com/u/688916" height="22" align="absmiddle" /></a> <a href="https://github.com/Startouf" align="absmiddle" ><img src="https://avatars2.githubusercontent.com/u/7388889" height="22" align="absmiddle" /></a> <a href="https://github.com/Tonkonozhenko" align="absmiddle" ><img src="https://avatars0.githubusercontent.com/u/1307646" height="22" align="absmiddle" /></a> <a href="https://github.com/mabako" align="absmiddle" ><img src="https://avatars3.githubusercontent.com/u/125113" height="22" align="absmiddle" /></a> <a href="https://github.com/frankzhao" align="absmiddle" ><img src="https://avatars3.githubusercontent.com/u/555499" height="22" align="absmiddle" /></a>
386
587
 
387
- :copyright: <a href="http://www.frontlineutilities.co.uk" align="absmiddle" ><img src="readme/fl.jpg" height="22" align="absmiddle" /></a> <a href="http://stackoverflow.com/users/1143732/richard-peck?tab=profile" align="absmiddle" ><img src="https://avatars0.githubusercontent.com/u/1104431" height="22" align="absmiddle" /></a>
388
588
 
389
589
  <!-- ################################### -->
390
590
  <!-- ################################### -->
@@ -432,5 +632,11 @@ To rollback, use the following:
432
632
  [pull]: http://github.com/richpeck/exception_handler/pulls
433
633
  [issues]: http://github.com/richpeck/exception_handler/issues
434
634
 
635
+ [10x]: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#1xx_Informational_responses
636
+ [20x]: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success
637
+ [30x]: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection
638
+ [40x]: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors
639
+ [50x]: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_errors
640
+
435
641
  <!-- ################################### -->
436
642
  <!-- ################################### -->