exception_engine 0.2.0

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 (54) hide show
  1. data/GPLv3.txt +674 -0
  2. data/Gemfile +12 -0
  3. data/Gemfile.lock +114 -0
  4. data/LICENSE.txt +17 -0
  5. data/README.rdoc +41 -0
  6. data/Rakefile +29 -0
  7. data/lib/exception_engine.rb +49 -0
  8. data/lib/exception_engine/backtrace.rb +100 -0
  9. data/lib/exception_engine/engine.rb +5 -0
  10. data/lib/exception_engine/exception_middleware.rb +21 -0
  11. data/lib/exception_engine/notice.rb +336 -0
  12. data/lib/exception_engine/version.rb +3 -0
  13. data/test/dummy/Rakefile +7 -0
  14. data/test/dummy/app/controllers/application_controller.rb +3 -0
  15. data/test/dummy/app/controllers/posts_controller.rb +5 -0
  16. data/test/dummy/app/helpers/application_helper.rb +2 -0
  17. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  18. data/test/dummy/config.ru +4 -0
  19. data/test/dummy/config/application.rb +45 -0
  20. data/test/dummy/config/boot.rb +10 -0
  21. data/test/dummy/config/database.yml +22 -0
  22. data/test/dummy/config/environment.rb +5 -0
  23. data/test/dummy/config/environments/development.rb +26 -0
  24. data/test/dummy/config/environments/production.rb +49 -0
  25. data/test/dummy/config/environments/test.rb +35 -0
  26. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  27. data/test/dummy/config/initializers/inflections.rb +10 -0
  28. data/test/dummy/config/initializers/mime_types.rb +5 -0
  29. data/test/dummy/config/initializers/secret_token.rb +7 -0
  30. data/test/dummy/config/initializers/session_store.rb +8 -0
  31. data/test/dummy/config/locales/en.yml +5 -0
  32. data/test/dummy/config/routes.rb +60 -0
  33. data/test/dummy/db/development.sqlite3 +0 -0
  34. data/test/dummy/db/test.sqlite3 +0 -0
  35. data/test/dummy/log/development.log +462 -0
  36. data/test/dummy/log/production.log +0 -0
  37. data/test/dummy/log/server.log +0 -0
  38. data/test/dummy/log/test.log +547 -0
  39. data/test/dummy/public/404.html +26 -0
  40. data/test/dummy/public/422.html +26 -0
  41. data/test/dummy/public/500.html +26 -0
  42. data/test/dummy/public/favicon.ico +0 -0
  43. data/test/dummy/public/javascripts/application.js +2 -0
  44. data/test/dummy/public/javascripts/controls.js +965 -0
  45. data/test/dummy/public/javascripts/dragdrop.js +974 -0
  46. data/test/dummy/public/javascripts/effects.js +1123 -0
  47. data/test/dummy/public/javascripts/prototype.js +6001 -0
  48. data/test/dummy/public/javascripts/rails.js +175 -0
  49. data/test/dummy/script/rails +6 -0
  50. data/test/exception_engine_test.rb +52 -0
  51. data/test/integration/navigation_test.rb +15 -0
  52. data/test/support/integration_case.rb +5 -0
  53. data/test/test_helper.rb +35 -0
  54. metadata +180 -0
@@ -0,0 +1,175 @@
1
+ (function() {
2
+ // Technique from Juriy Zaytsev
3
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4
+ function isEventSupported(eventName) {
5
+ var el = document.createElement('div');
6
+ eventName = 'on' + eventName;
7
+ var isSupported = (eventName in el);
8
+ if (!isSupported) {
9
+ el.setAttribute(eventName, 'return;');
10
+ isSupported = typeof el[eventName] == 'function';
11
+ }
12
+ el = null;
13
+ return isSupported;
14
+ }
15
+
16
+ function isForm(element) {
17
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18
+ }
19
+
20
+ function isInput(element) {
21
+ if (Object.isElement(element)) {
22
+ var name = element.nodeName.toUpperCase()
23
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24
+ }
25
+ else return false
26
+ }
27
+
28
+ var submitBubbles = isEventSupported('submit'),
29
+ changeBubbles = isEventSupported('change')
30
+
31
+ if (!submitBubbles || !changeBubbles) {
32
+ // augment the Event.Handler class to observe custom events when needed
33
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34
+ function(init, element, eventName, selector, callback) {
35
+ init(element, eventName, selector, callback)
36
+ // is the handler being attached to an element that doesn't support this event?
37
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39
+ // "submit" => "emulated:submit"
40
+ this.eventName = 'emulated:' + this.eventName
41
+ }
42
+ }
43
+ )
44
+ }
45
+
46
+ if (!submitBubbles) {
47
+ // discover forms on the page by observing focus events which always bubble
48
+ document.on('focusin', 'form', function(focusEvent, form) {
49
+ // special handler for the real "submit" event (one-time operation)
50
+ if (!form.retrieve('emulated:submit')) {
51
+ form.on('submit', function(submitEvent) {
52
+ var emulated = form.fire('emulated:submit', submitEvent, true)
53
+ // if custom event received preventDefault, cancel the real one too
54
+ if (emulated.returnValue === false) submitEvent.preventDefault()
55
+ })
56
+ form.store('emulated:submit', true)
57
+ }
58
+ })
59
+ }
60
+
61
+ if (!changeBubbles) {
62
+ // discover form inputs on the page
63
+ document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64
+ // special handler for real "change" events
65
+ if (!input.retrieve('emulated:change')) {
66
+ input.on('change', function(changeEvent) {
67
+ input.fire('emulated:change', changeEvent, true)
68
+ })
69
+ input.store('emulated:change', true)
70
+ }
71
+ })
72
+ }
73
+
74
+ function handleRemote(element) {
75
+ var method, url, params;
76
+
77
+ var event = element.fire("ajax:before");
78
+ if (event.stopped) return false;
79
+
80
+ if (element.tagName.toLowerCase() === 'form') {
81
+ method = element.readAttribute('method') || 'post';
82
+ url = element.readAttribute('action');
83
+ params = element.serialize();
84
+ } else {
85
+ method = element.readAttribute('data-method') || 'get';
86
+ url = element.readAttribute('href');
87
+ params = {};
88
+ }
89
+
90
+ new Ajax.Request(url, {
91
+ method: method,
92
+ parameters: params,
93
+ evalScripts: true,
94
+
95
+ onComplete: function(request) { element.fire("ajax:complete", request); },
96
+ onSuccess: function(request) { element.fire("ajax:success", request); },
97
+ onFailure: function(request) { element.fire("ajax:failure", request); }
98
+ });
99
+
100
+ element.fire("ajax:after");
101
+ }
102
+
103
+ function handleMethod(element) {
104
+ var method = element.readAttribute('data-method'),
105
+ url = element.readAttribute('href'),
106
+ csrf_param = $$('meta[name=csrf-param]')[0],
107
+ csrf_token = $$('meta[name=csrf-token]')[0];
108
+
109
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110
+ element.parentNode.insert(form);
111
+
112
+ if (method !== 'post') {
113
+ var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114
+ form.insert(field);
115
+ }
116
+
117
+ if (csrf_param) {
118
+ var param = csrf_param.readAttribute('content'),
119
+ token = csrf_token.readAttribute('content'),
120
+ field = new Element('input', { type: 'hidden', name: param, value: token });
121
+ form.insert(field);
122
+ }
123
+
124
+ form.submit();
125
+ }
126
+
127
+
128
+ document.on("click", "*[data-confirm]", function(event, element) {
129
+ var message = element.readAttribute('data-confirm');
130
+ if (!confirm(message)) event.stop();
131
+ });
132
+
133
+ document.on("click", "a[data-remote]", function(event, element) {
134
+ if (event.stopped) return;
135
+ handleRemote(element);
136
+ event.stop();
137
+ });
138
+
139
+ document.on("click", "a[data-method]", function(event, element) {
140
+ if (event.stopped) return;
141
+ handleMethod(element);
142
+ event.stop();
143
+ });
144
+
145
+ document.on("submit", function(event) {
146
+ var element = event.findElement(),
147
+ message = element.readAttribute('data-confirm');
148
+ if (message && !confirm(message)) {
149
+ event.stop();
150
+ return false;
151
+ }
152
+
153
+ var inputs = element.select("input[type=submit][data-disable-with]");
154
+ inputs.each(function(input) {
155
+ input.disabled = true;
156
+ input.writeAttribute('data-original-value', input.value);
157
+ input.value = input.readAttribute('data-disable-with');
158
+ });
159
+
160
+ var element = event.findElement("form[data-remote]");
161
+ if (element) {
162
+ handleRemote(element);
163
+ event.stop();
164
+ }
165
+ });
166
+
167
+ document.on("ajax:after", "form", function(event, element) {
168
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169
+ inputs.each(function(input) {
170
+ input.value = input.readAttribute('data-original-value');
171
+ input.removeAttribute('data-original-value');
172
+ input.disabled = false;
173
+ });
174
+ });
175
+ })();
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,52 @@
1
+ require 'test_helper'
2
+
3
+ class ExceptionMiddlewareTest < ActiveSupport::TestCase
4
+
5
+ test "call the upstream app with the environment" do
6
+ environment = { 'key' => 'value' }
7
+ app = lambda { |env| ['response', {}, env] }
8
+ stack = ExceptionEngine::ExceptionMiddleware.new(app)
9
+
10
+ response = stack.call(environment)
11
+
12
+ assert_equal ['response', {}, environment], response
13
+ end
14
+
15
+ test "deliver an exception raised while calling an upstream app" do
16
+
17
+ exception = build_exception
18
+ environment = { 'key' => 'value' }
19
+ app = lambda do |env|
20
+ raise exception
21
+ end
22
+
23
+ begin
24
+ stack = ExceptionEngine::ExceptionMiddleware.new(app)
25
+ stack.call(environment)
26
+ rescue Exception => raised
27
+ assert_equal exception, raised
28
+ else
29
+ flunk "Didn't raise an exception"
30
+ end
31
+
32
+ end
33
+
34
+ test "deliver an exception in rack.exception" do
35
+
36
+ exception = build_exception
37
+ environment = { 'key' => 'value' }
38
+
39
+ response = [200, {}, ['okay']]
40
+ app = lambda do |env|
41
+ env['rack.exception'] = exception
42
+ response
43
+ end
44
+ stack = ExceptionEngine::ExceptionMiddleware.new(app)
45
+
46
+ actual_response = stack.call(environment)
47
+
48
+ assert_equal response, actual_response
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ class NavigationTest < ActiveSupport::IntegrationCase
4
+ test "can visualize the exceptions in the rails log" do
5
+
6
+ # PostsController has an index with a failing constant call
7
+ begin
8
+ visit "/posts"
9
+ rescue
10
+ # Check for exception data on the page
11
+ visit exceptions_path
12
+ assert_match "uninitialized constant PostsController::Post", page.body
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ # Define a bare test case to use with Capybara
2
+ class ActiveSupport::IntegrationCase < ActiveSupport::TestCase
3
+ include Capybara
4
+ include Rails.application.routes.url_helpers
5
+ end
@@ -0,0 +1,35 @@
1
+ # Configure Rails Envinronment
2
+ ENV["RAILS_ENV"] = "test"
3
+
4
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
+ require "rails/test_help"
6
+
7
+ ActionMailer::Base.delivery_method = :test
8
+ ActionMailer::Base.perform_deliveries = true
9
+ ActionMailer::Base.default_url_options[:host] = "test.com"
10
+
11
+ Rails.backtrace_cleaner.remove_silencers!
12
+
13
+ # Configure capybara for integration testing
14
+ require "capybara/rails"
15
+ Capybara.default_driver = :rack_test
16
+ Capybara.default_selector = :css
17
+
18
+ # Run any available migration
19
+ ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__)
20
+
21
+ # Load support files
22
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
23
+
24
+ # Helper methods
25
+ class ActiveSupport::TestCase
26
+ setup { ExceptionEngine::Data.delete_all }
27
+
28
+ # Creates RunTimeError
29
+ def build_exception
30
+ raise
31
+ rescue => caught_exception
32
+ caught_exception
33
+ end
34
+ end
35
+
metadata ADDED
@@ -0,0 +1,180 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: exception_engine
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.2.0
6
+ platform: ruby
7
+ authors:
8
+ - Muhammad Fadhli Rahim
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-02-09 00:00:00 +08:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: mongoid
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - "="
23
+ - !ruby/object:Gem::Version
24
+ version: 2.0.0.rc.5
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: mongo
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - "="
34
+ - !ruby/object:Gem::Version
35
+ version: 1.1.5
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: bson_ext
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - "="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.2.0
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ description: The Exception Engine logs your Rails exceptions in your mongodb database and provides a web interface to manage them
50
+ email: fadhlirahim@gmail.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - lib/exception_engine/backtrace.rb
59
+ - lib/exception_engine/engine.rb
60
+ - lib/exception_engine/exception_middleware.rb
61
+ - lib/exception_engine/notice.rb
62
+ - lib/exception_engine/version.rb
63
+ - lib/exception_engine.rb
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - GPLv3.txt
67
+ - LICENSE.txt
68
+ - Rakefile
69
+ - README.rdoc
70
+ - test/dummy/app/controllers/application_controller.rb
71
+ - test/dummy/app/controllers/posts_controller.rb
72
+ - test/dummy/app/helpers/application_helper.rb
73
+ - test/dummy/app/views/layouts/application.html.erb
74
+ - test/dummy/config/application.rb
75
+ - test/dummy/config/boot.rb
76
+ - test/dummy/config/database.yml
77
+ - test/dummy/config/environment.rb
78
+ - test/dummy/config/environments/development.rb
79
+ - test/dummy/config/environments/production.rb
80
+ - test/dummy/config/environments/test.rb
81
+ - test/dummy/config/initializers/backtrace_silencers.rb
82
+ - test/dummy/config/initializers/inflections.rb
83
+ - test/dummy/config/initializers/mime_types.rb
84
+ - test/dummy/config/initializers/secret_token.rb
85
+ - test/dummy/config/initializers/session_store.rb
86
+ - test/dummy/config/locales/en.yml
87
+ - test/dummy/config/routes.rb
88
+ - test/dummy/config.ru
89
+ - test/dummy/db/development.sqlite3
90
+ - test/dummy/db/test.sqlite3
91
+ - test/dummy/log/development.log
92
+ - test/dummy/log/production.log
93
+ - test/dummy/log/server.log
94
+ - test/dummy/log/test.log
95
+ - test/dummy/public/404.html
96
+ - test/dummy/public/422.html
97
+ - test/dummy/public/500.html
98
+ - test/dummy/public/favicon.ico
99
+ - test/dummy/public/javascripts/application.js
100
+ - test/dummy/public/javascripts/controls.js
101
+ - test/dummy/public/javascripts/dragdrop.js
102
+ - test/dummy/public/javascripts/effects.js
103
+ - test/dummy/public/javascripts/prototype.js
104
+ - test/dummy/public/javascripts/rails.js
105
+ - test/dummy/Rakefile
106
+ - test/dummy/script/rails
107
+ - test/exception_engine_test.rb
108
+ - test/integration/navigation_test.rb
109
+ - test/support/integration_case.rb
110
+ - test/test_helper.rb
111
+ has_rdoc: true
112
+ homepage: http://github.com/Consoci8/exception_engine
113
+ licenses: []
114
+
115
+ post_install_message:
116
+ rdoc_options: []
117
+
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: "0"
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: "0"
132
+ requirements: []
133
+
134
+ rubyforge_project:
135
+ rubygems_version: 1.5.0
136
+ signing_key:
137
+ specification_version: 3
138
+ summary: A rails engine that logs your Rails exceptions
139
+ test_files:
140
+ - test/dummy/app/controllers/application_controller.rb
141
+ - test/dummy/app/controllers/posts_controller.rb
142
+ - test/dummy/app/helpers/application_helper.rb
143
+ - test/dummy/app/views/layouts/application.html.erb
144
+ - test/dummy/config/application.rb
145
+ - test/dummy/config/boot.rb
146
+ - test/dummy/config/database.yml
147
+ - test/dummy/config/environment.rb
148
+ - test/dummy/config/environments/development.rb
149
+ - test/dummy/config/environments/production.rb
150
+ - test/dummy/config/environments/test.rb
151
+ - test/dummy/config/initializers/backtrace_silencers.rb
152
+ - test/dummy/config/initializers/inflections.rb
153
+ - test/dummy/config/initializers/mime_types.rb
154
+ - test/dummy/config/initializers/secret_token.rb
155
+ - test/dummy/config/initializers/session_store.rb
156
+ - test/dummy/config/locales/en.yml
157
+ - test/dummy/config/routes.rb
158
+ - test/dummy/config.ru
159
+ - test/dummy/db/development.sqlite3
160
+ - test/dummy/db/test.sqlite3
161
+ - test/dummy/log/development.log
162
+ - test/dummy/log/production.log
163
+ - test/dummy/log/server.log
164
+ - test/dummy/log/test.log
165
+ - test/dummy/public/404.html
166
+ - test/dummy/public/422.html
167
+ - test/dummy/public/500.html
168
+ - test/dummy/public/favicon.ico
169
+ - test/dummy/public/javascripts/application.js
170
+ - test/dummy/public/javascripts/controls.js
171
+ - test/dummy/public/javascripts/dragdrop.js
172
+ - test/dummy/public/javascripts/effects.js
173
+ - test/dummy/public/javascripts/prototype.js
174
+ - test/dummy/public/javascripts/rails.js
175
+ - test/dummy/Rakefile
176
+ - test/dummy/script/rails
177
+ - test/exception_engine_test.rb
178
+ - test/integration/navigation_test.rb
179
+ - test/support/integration_case.rb
180
+ - test/test_helper.rb