request_exception_handler 0.4 → 0.5.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.
- checksums.yaml +7 -0
- data/LICENSE +1 -1
- data/README.md +44 -34
- data/lib/request_exception_handler.rb +92 -35
- data/test/_test-unit-rails4.rb +62 -0
- data/test/request_exception_handler_test.rb +55 -65
- data/test/test_helper.rb +73 -35
- metadata +71 -86
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 161f65acac0facbace5cd9ca6c97b5505d6eb37f
|
4
|
+
data.tar.gz: 1cc3a96669b70eb6b2b78cb7f946674ca4eed339
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8f4cb1cac97ae79f15d49a7eaaab3773a432b01363ec4192fdb19c53a01845d65aff075063d271c17bc60baed6c1468f207924c73719f19860a52d8e6a5a6b7b
|
7
|
+
data.tar.gz: 068f53859e8c7d8f058f4337712dc36d1eebbde96d92aee7cffda6ef87fc504b9ef27f74d4c2c99182bc00578924ef703ccd99501f756fae576aa0329ef822fc
|
data/LICENSE
CHANGED
@@ -186,7 +186,7 @@
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
187
187
|
identification within third-party archives.
|
188
188
|
|
189
|
-
Copyright (c)
|
189
|
+
Copyright (c) 2014 Karol Bucek
|
190
190
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
192
192
|
you may not use this file except in compliance with the License.
|
data/README.md
CHANGED
@@ -1,71 +1,81 @@
|
|
1
1
|
# RequestExceptionHandler
|
2
2
|
|
3
3
|
Rails is not capable of calling your exception handlers when an error occurs
|
4
|
-
during the parsing of request parameters (e.g. in case of invalid
|
4
|
+
during the parsing of request parameters (e.g. in case of invalid JSON body).
|
5
5
|
|
6
|
-
This will hopefully change someday, but until then I have created this
|
7
|
-
monkey-patch for request parameter
|
6
|
+
This will hopefully change someday, but until then I have created this delicate
|
7
|
+
monkey-patch for the request parameter parser to allow more flexibility when
|
8
8
|
an invalid request body is received.
|
9
9
|
|
10
|
-
Tested on
|
10
|
+
Tested on 4.x and 3.x but it should still work on Rails 2.3 and 2.2.3 as well.
|
11
11
|
|
12
|
+
[![Build Status][0]](http://travis-ci.org/#!/kares/request_exception_handler)
|
12
13
|
|
13
14
|
## Install
|
14
15
|
|
15
16
|
gem 'request_exception_handler'
|
16
17
|
|
17
|
-
or as a plain-old rails plugin :
|
18
|
+
~~or as a plain-old (obsolete) rails plugin~~ :
|
18
19
|
|
19
20
|
script/plugin install git://github.com/kares/request_exception_handler.git
|
20
21
|
|
21
22
|
## Example
|
22
23
|
|
23
24
|
The code hooks into parameter parsing and allows a request to be constructed
|
24
|
-
even if the
|
25
|
-
filter is installed that checks for a request exception
|
26
|
-
it seems to Rails that the exception comes from the
|
27
|
-
processed as all other "business" exceptions.
|
28
|
-
you might skip this filter and install your own to handle such cases (it's good
|
29
|
-
to make sure the filter gets to the beginning of the chain) :
|
25
|
+
even if the parsing of the submitted raw content fails (JSON/XML backend raises
|
26
|
+
a parse error). A before filter is installed that checks for a request exception
|
27
|
+
and re-raises, it thus it seems to Rails that the exception comes from the
|
28
|
+
application code and is processed as all other "business" exceptions.
|
30
29
|
|
31
|
-
|
30
|
+
One might skip this "request-exception" filter (e.g. per action - the usual way)
|
31
|
+
and install another to handle such cases (it's good to make sure the filter gets
|
32
|
+
at the beginning of the chain) :
|
32
33
|
|
33
|
-
|
34
|
+
```ruby
|
35
|
+
class MyController < ApplicationController
|
34
36
|
|
35
|
-
|
36
|
-
prepend_before_filter :return_409_on_json_errors
|
37
|
+
skip_before_filter :check_request_exception # filter the plugin installed
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
def return_409_on_json_errors
|
41
|
-
if re = request_exception && re.is_a?(ActiveSupport::JSON::ParseError)
|
42
|
-
head 409
|
43
|
-
else
|
44
|
-
head 500
|
45
|
-
end
|
46
|
-
end
|
39
|
+
# custom before filter use request_exception to detect occured errors
|
40
|
+
prepend_before_filter :return_409_on_json_errors
|
47
41
|
|
42
|
+
private
|
43
|
+
def return_409_on_json_errors
|
44
|
+
if e = request_exception && e.is_a?(ActiveSupport::JSON::ParseError)
|
45
|
+
head 409
|
46
|
+
else
|
47
|
+
head 500
|
48
48
|
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
```
|
49
53
|
|
50
54
|
Another option of how to modify the returned 500 status is to use exception
|
51
55
|
handlers the same way you're (hopefully) using them for your own exceptions :
|
52
56
|
|
53
|
-
|
57
|
+
```ruby
|
58
|
+
class ApplicationController < ActionController::Base
|
54
59
|
|
55
|
-
|
56
|
-
|
57
|
-
|
60
|
+
rescue_from 'REXML::ParseException' do |exception|
|
61
|
+
render :text => exception.to_s, :status => 422
|
62
|
+
end
|
58
63
|
|
59
|
-
|
64
|
+
end
|
65
|
+
```
|
60
66
|
|
61
67
|
If you're not using REXML as a parsing backend the exception might vary, e.g.
|
62
68
|
for Nokogiri the rescue block would look something like :
|
63
69
|
|
64
|
-
|
65
|
-
|
66
|
-
|
70
|
+
```ruby
|
71
|
+
rescue_from 'Nokogiri::XML::SyntaxError' do |exception|
|
72
|
+
render :text => exception.to_s, :status => 422
|
73
|
+
end
|
74
|
+
```
|
67
75
|
|
68
76
|
## Copyright
|
69
77
|
|
70
|
-
Copyright (c)
|
71
|
-
See LICENSE (http://www.apache.org/licenses/LICENSE-2.0) for details.
|
78
|
+
Copyright (c) 2014 [Karol Bucek](https://github.com/kares).
|
79
|
+
See LICENSE (http://www.apache.org/licenses/LICENSE-2.0) for details.
|
80
|
+
|
81
|
+
[0]: https://secure.travis-ci.org/kares/request_exception_handler.png
|
@@ -3,31 +3,35 @@
|
|
3
3
|
module RequestExceptionHandler
|
4
4
|
|
5
5
|
THREAD_LOCAL_NAME = :_request_exception
|
6
|
-
|
6
|
+
|
7
7
|
@@parse_request_parameters_exception_handler = lambda do |request, exception|
|
8
|
-
|
8
|
+
RequestExceptionHandler.store_request_exception(exception)
|
9
9
|
request_body = request.respond_to?(:body) ? request.body : request.raw_post
|
10
10
|
|
11
11
|
logger = RequestExceptionHandler.logger
|
12
|
-
if logger.
|
12
|
+
if logger.debug?
|
13
13
|
content_log = request_body
|
14
14
|
if request_body.is_a?(StringIO)
|
15
15
|
pos = request_body.pos
|
16
16
|
content_log = request_body.read
|
17
17
|
end
|
18
|
-
logger.
|
19
|
-
|
18
|
+
logger.debug "#{exception.class.name} occurred while parsing request parameters." <<
|
19
|
+
"\nContents:\n#{content_log}\n"
|
20
20
|
request_body.pos = pos if pos
|
21
|
+
elsif logger.info?
|
22
|
+
logger.info "#{exception.class.name} occurred while parsing request parameters."
|
21
23
|
end
|
22
|
-
|
23
|
-
content_type = if request.respond_to?(:
|
24
|
-
request.
|
25
|
-
|
26
|
-
request.
|
24
|
+
|
25
|
+
content_type = if request.respond_to?(:content_mime_type)
|
26
|
+
request.content_mime_type
|
27
|
+
elsif request.respond_to?(:content_type_with_parameters)
|
28
|
+
request.send :content_type_with_parameters # (legacy) ActionController::AbstractRequest
|
29
|
+
else
|
30
|
+
request.content_type
|
27
31
|
end
|
28
32
|
{ "body" => request_body, "content_type" => content_type, "content_length" => request.content_length }
|
29
33
|
end
|
30
|
-
|
34
|
+
|
31
35
|
begin
|
32
36
|
mattr_accessor :parse_request_parameters_exception_handler
|
33
37
|
rescue NoMethodError => e
|
@@ -35,34 +39,62 @@ module RequestExceptionHandler
|
|
35
39
|
raise e
|
36
40
|
end
|
37
41
|
|
38
|
-
|
39
|
-
def self.reset_request_exception
|
40
|
-
Thread.current[THREAD_LOCAL_NAME] = nil
|
41
|
-
end
|
42
|
+
@@parse_request_parameters_exception_logger = nil
|
42
43
|
|
43
44
|
# Retrieves the Rails logger.
|
44
45
|
def self.logger
|
45
|
-
|
46
|
-
defined?(
|
47
|
-
|
46
|
+
@@parse_request_parameters_exception_logger ||=
|
47
|
+
defined?(Rails.logger) ? Rails.logger :
|
48
|
+
defined?(RAILS_DEFAULT_LOGGER) ? RAILS_DEFAULT_LOGGER :
|
49
|
+
Logger.new(STDERR)
|
48
50
|
end
|
49
|
-
|
51
|
+
|
50
52
|
def self.included(base)
|
51
53
|
base.prepend_before_filter :check_request_exception
|
52
54
|
end
|
53
55
|
|
54
|
-
#
|
55
|
-
def
|
56
|
-
|
57
|
-
|
56
|
+
# Resets the current +request_exception+ (to nil).
|
57
|
+
def self.reset_request_exception
|
58
|
+
store_request_exception nil
|
59
|
+
end
|
60
|
+
|
61
|
+
if defined? Thread.current.thread_variables
|
62
|
+
|
63
|
+
# Resets the current +request_exception+ (to nil).
|
64
|
+
def self.store_request_exception(exception)
|
65
|
+
Thread.current.thread_variable_set THREAD_LOCAL_NAME, exception
|
66
|
+
end
|
67
|
+
|
68
|
+
# Retrieves and keeps track of the current request exception if any.
|
69
|
+
def request_exception
|
70
|
+
return @_request_exception if defined? @_request_exception
|
71
|
+
@_request_exception = Thread.current.thread_variable_get(THREAD_LOCAL_NAME)
|
72
|
+
RequestExceptionHandler.reset_request_exception
|
73
|
+
@_request_exception
|
74
|
+
end
|
75
|
+
|
76
|
+
else
|
77
|
+
|
78
|
+
# Resets the current +request_exception+ (to nil).
|
79
|
+
def self.store_request_exception(exception)
|
80
|
+
Thread.current[THREAD_LOCAL_NAME] = exception
|
81
|
+
end
|
82
|
+
|
83
|
+
# Retrieves and keeps track of the current request exception if any.
|
84
|
+
def request_exception
|
85
|
+
return @_request_exception if defined? @_request_exception
|
86
|
+
@_request_exception = Thread.current[THREAD_LOCAL_NAME]
|
87
|
+
RequestExceptionHandler.reset_request_exception
|
88
|
+
@_request_exception
|
89
|
+
end
|
90
|
+
|
58
91
|
end
|
59
92
|
|
60
|
-
#
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
@_request_exception
|
93
|
+
# Checks and raises a +request_exception+ (gets prepended as a before filter).
|
94
|
+
def check_request_exception
|
95
|
+
if e = request_exception
|
96
|
+
raise e if e.is_a?(Exception)
|
97
|
+
end
|
66
98
|
end
|
67
99
|
|
68
100
|
end
|
@@ -70,11 +102,36 @@ end
|
|
70
102
|
require 'action_controller/base'
|
71
103
|
ActionController::Base.send :include, RequestExceptionHandler
|
72
104
|
|
73
|
-
# NOTE: Rails monkey patching follows :
|
105
|
+
# NOTE: Rails "parameters-parser" monkey patching follows :
|
106
|
+
|
107
|
+
if defined? ActionDispatch::ParamsParser::ParseError # Rails 4.x
|
108
|
+
|
109
|
+
class ActionDispatch::ParamsParser
|
110
|
+
|
111
|
+
alias_method 'parse_formatted_parameters_without_exception_handler', 'parse_formatted_parameters'
|
112
|
+
|
113
|
+
def parse_formatted_parameters_with_exception_handler(env)
|
114
|
+
begin
|
115
|
+
out = parse_formatted_parameters_without_exception_handler(env)
|
116
|
+
RequestExceptionHandler.reset_request_exception # make sure it's nil
|
117
|
+
out
|
118
|
+
rescue ParseError => e
|
119
|
+
e = e.original_exception
|
120
|
+
handler = RequestExceptionHandler.parse_request_parameters_exception_handler
|
121
|
+
handler ? handler.call(ActionDispatch::Request.new(env), e) : raise
|
122
|
+
rescue => e # all Exception-s get wrapped into ParseError ... but just in case
|
123
|
+
handler = RequestExceptionHandler.parse_request_parameters_exception_handler
|
124
|
+
handler ? handler.call(ActionDispatch::Request.new(env), e) : raise
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
alias_method 'parse_formatted_parameters', 'parse_formatted_parameters_with_exception_handler'
|
129
|
+
|
130
|
+
end
|
74
131
|
|
75
|
-
|
132
|
+
elsif defined? ActionDispatch::ParamsParser # Rails 3.x
|
76
133
|
|
77
|
-
ActionDispatch::ParamsParser
|
134
|
+
class ActionDispatch::ParamsParser
|
78
135
|
|
79
136
|
def parse_formatted_parameters_with_exception_handler(env)
|
80
137
|
begin
|
@@ -87,13 +144,13 @@ if defined? ActionDispatch::ParamsParser # Rails 3.x
|
|
87
144
|
end
|
88
145
|
end
|
89
146
|
|
90
|
-
alias_method_chain
|
147
|
+
alias_method_chain 'parse_formatted_parameters', 'exception_handler'
|
91
148
|
|
92
149
|
end
|
93
150
|
|
94
151
|
elsif defined? ActionController::ParamsParser # Rails 2.3.x
|
95
152
|
|
96
|
-
ActionController::ParamsParser
|
153
|
+
class ActionController::ParamsParser
|
97
154
|
|
98
155
|
def parse_formatted_parameters_with_exception_handler(env)
|
99
156
|
begin
|
@@ -106,7 +163,7 @@ elsif defined? ActionController::ParamsParser # Rails 2.3.x
|
|
106
163
|
end
|
107
164
|
end
|
108
165
|
|
109
|
-
alias_method_chain
|
166
|
+
alias_method_chain 'parse_formatted_parameters', 'exception_handler'
|
110
167
|
|
111
168
|
end
|
112
169
|
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# mock require 'active_support/testing/autorun'
|
2
|
+
$LOADED_FEATURES << 'active_support/testing/autorun.rb'
|
3
|
+
require 'test-unit'
|
4
|
+
##
|
5
|
+
|
6
|
+
# mock require 'active_support/test_case'
|
7
|
+
$LOADED_FEATURES << 'active_support/test_case.rb'
|
8
|
+
|
9
|
+
require 'active_support/testing/tagged_logging'
|
10
|
+
require 'active_support/testing/setup_and_teardown' # ?
|
11
|
+
require 'active_support/testing/assertions'
|
12
|
+
require 'active_support/testing/deprecation'
|
13
|
+
#require 'active_support/testing/pending'
|
14
|
+
#require 'active_support/testing/declarative'
|
15
|
+
#require 'active_support/testing/isolation'
|
16
|
+
require 'active_support/testing/constant_lookup'
|
17
|
+
require 'active_support/core_ext/kernel/reporting'
|
18
|
+
require 'active_support/deprecation'
|
19
|
+
|
20
|
+
#begin
|
21
|
+
# silence_warnings { require 'mocha/setup' }
|
22
|
+
#rescue LoadError
|
23
|
+
#end
|
24
|
+
|
25
|
+
module ActiveSupport
|
26
|
+
class TestCase < Test::Unit::TestCase
|
27
|
+
#Assertion = Test::Unit::Assertions
|
28
|
+
|
29
|
+
@@tags = {}
|
30
|
+
def self.for_tag(tag)
|
31
|
+
yield if @@tags[tag]
|
32
|
+
end
|
33
|
+
|
34
|
+
include ActiveSupport::Testing::TaggedLogging
|
35
|
+
include ActiveSupport::Testing::SetupAndTeardown
|
36
|
+
include ActiveSupport::Testing::Assertions
|
37
|
+
include ActiveSupport::Testing::Deprecation
|
38
|
+
#include ActiveSupport::Testing::Pending
|
39
|
+
#extend ActiveSupport::Testing::Declarative
|
40
|
+
|
41
|
+
# Fails if the block raises an exception.
|
42
|
+
#
|
43
|
+
# assert_nothing_raised do
|
44
|
+
# ...
|
45
|
+
# end
|
46
|
+
#def assert_nothing_raised(*args)
|
47
|
+
# yield
|
48
|
+
#end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
|
54
|
+
#require "test/unit/active_support"
|
55
|
+
#require "test/unit/notify"
|
56
|
+
#require "test/unit/rr"
|
57
|
+
|
58
|
+
# due ActionDispatch::Integration
|
59
|
+
$LOADED_FEATURES << 'minitest/unit.rb'
|
60
|
+
module MiniTest
|
61
|
+
Assertions = Test::Unit::Assertions
|
62
|
+
end
|
@@ -1,28 +1,15 @@
|
|
1
1
|
require File.expand_path('test_helper', File.dirname(__FILE__))
|
2
2
|
|
3
|
-
#
|
4
|
-
# NOTE: due to the test_helper.rb argument parsing this test might
|
5
|
-
# be run with different versions of Rails e.g. :
|
6
|
-
#
|
7
|
-
# ruby request_exception_handler_test.rb RAILS_VERSION=2.1.2
|
8
|
-
#
|
9
|
-
|
10
3
|
class TestController < ActionController::Base
|
11
4
|
|
12
|
-
def parse
|
13
|
-
head :ok
|
14
|
-
end
|
5
|
+
def parse; head :ok end
|
15
6
|
|
16
|
-
def parse_with_check_request_exception_skipped
|
17
|
-
head :ok
|
18
|
-
end
|
7
|
+
def parse_with_check_request_exception_skipped; head :ok end
|
19
8
|
|
20
9
|
skip_before_filter :check_request_exception, :only =>
|
21
10
|
[ :parse_with_check_request_exception_skipped, :parse_with_check_request_exception_replaced ]
|
22
11
|
|
23
|
-
def parse_with_check_request_exception_replaced
|
24
|
-
head :ok
|
25
|
-
end
|
12
|
+
def parse_with_check_request_exception_replaced; head :ok end
|
26
13
|
|
27
14
|
before_filter :return_501_on_request_exception, :only => [ :parse_with_check_request_exception_replaced ]
|
28
15
|
|
@@ -38,9 +25,7 @@ class TestWithRexmlRescueController < ActionController::Base
|
|
38
25
|
render :text => exception.class.name, :status => 405
|
39
26
|
end
|
40
27
|
|
41
|
-
def index
|
42
|
-
head :ok
|
43
|
-
end
|
28
|
+
def index; head :ok end
|
44
29
|
|
45
30
|
end
|
46
31
|
|
@@ -50,21 +35,19 @@ class TestWithNokogiriRescueController < ActionController::Base
|
|
50
35
|
render :text => exception.class.name, :status => 505
|
51
36
|
end
|
52
37
|
|
53
|
-
def index
|
54
|
-
head :ok
|
55
|
-
end
|
38
|
+
def index; head :ok end
|
56
39
|
|
57
40
|
end
|
58
41
|
|
59
|
-
if Rails
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
42
|
+
if Rails::VERSION::MAJOR >= 4
|
43
|
+
RequestExceptionHandlerTest::Application.routes.draw do
|
44
|
+
post "/parse_with_rexml_rescue_block", :to => 'test_with_rexml_rescue#index'
|
45
|
+
post "/parse_with_nokogiri_rescue_block", :to => 'test_with_nokogiri_rescue#index'
|
46
|
+
post '/parse' => "test#parse"
|
47
|
+
post '/parse_with_check_request_exception_skipped', :to => "test#parse_with_check_request_exception_skipped"
|
48
|
+
post '/parse_with_check_request_exception_replaced', :to => "test#parse_with_check_request_exception_replaced"
|
66
49
|
end
|
67
|
-
|
50
|
+
elsif Rails::VERSION::MAJOR >= 3
|
68
51
|
RequestExceptionHandlerTest::Application.routes.draw do
|
69
52
|
match "/parse_with_rexml_rescue_block", :to => 'test_with_rexml_rescue#index'
|
70
53
|
match "/parse_with_nokogiri_rescue_block", :to => 'test_with_nokogiri_rescue#index'
|
@@ -72,9 +55,17 @@ else
|
|
72
55
|
match '/parse_with_check_request_exception_skipped', :to => "test#parse_with_check_request_exception_skipped"
|
73
56
|
match '/parse_with_check_request_exception_replaced', :to => "test#parse_with_check_request_exception_replaced"
|
74
57
|
end
|
58
|
+
else
|
59
|
+
ActionController::Routing::Routes.draw do |map|
|
60
|
+
map.connect '/parse_with_rexml_rescue_block',
|
61
|
+
:controller => 'test_with_rexml_rescue', :action => 'index'
|
62
|
+
map.connect '/parse_with_nokogiri_rescue_block',
|
63
|
+
:controller => 'test_with_nokogiri_rescue', :action => 'index'
|
64
|
+
map.connect '/:action', :controller => "test"
|
65
|
+
end
|
75
66
|
end
|
76
67
|
|
77
|
-
class RequestExceptionHandlerJsonTest <
|
68
|
+
class RequestExceptionHandlerJsonTest < IntegrationTest
|
78
69
|
|
79
70
|
def test_parse_valid_json
|
80
71
|
post "/parse", '{"cicinbrus": {"name": "Ferko"}}', 'CONTENT_TYPE' => 'application/json'
|
@@ -94,18 +85,18 @@ class RequestExceptionHandlerJsonTest < ActionController::IntegrationTest
|
|
94
85
|
|
95
86
|
private
|
96
87
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
88
|
+
def assert_json_parse_exception(error)
|
89
|
+
if ActiveSupport::JSON.respond_to?(:parse_error) # 2.3.5
|
90
|
+
parse_error_class = ActiveSupport::JSON.parse_error
|
91
|
+
assert_instance_of parse_error_class, error
|
92
|
+
else
|
93
|
+
assert_instance_of ActiveSupport::JSON::ParseError, error
|
104
94
|
end
|
95
|
+
end
|
105
96
|
|
106
97
|
end
|
107
98
|
|
108
|
-
class RequestExceptionHandlerXmlTest <
|
99
|
+
class RequestExceptionHandlerXmlTest < IntegrationTest
|
109
100
|
|
110
101
|
def test_parse_valid_xml
|
111
102
|
post "/parse", "<cicinbrus> <name>Ferko</name> </cicinbrus>", 'CONTENT_TYPE' => 'application/xml'
|
@@ -167,35 +158,34 @@ class RequestExceptionHandlerXmlTest < ActionController::IntegrationTest
|
|
167
158
|
assert_response 405
|
168
159
|
end
|
169
160
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
require 'nokogiri'
|
176
|
-
rescue LoadError
|
177
|
-
:nil
|
178
|
-
end
|
179
|
-
if nokogiri != :nil
|
180
|
-
backend = ActiveSupport::XmlMini.backend
|
181
|
-
begin
|
182
|
-
ActiveSupport::XmlMini.backend = 'Nokogiri'
|
183
|
-
post "/parse_with_nokogiri_rescue_block", "<cicinbrus> <name>Ferko</name>", 'CONTENT_TYPE' => 'application/xml'
|
184
|
-
assert_response 505
|
185
|
-
ensure
|
186
|
-
ActiveSupport::XmlMini.backend = backend
|
187
|
-
end
|
188
|
-
else
|
189
|
-
puts "nokogiri not available - test skipped !"
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
161
|
+
begin
|
162
|
+
require 'nokogiri'
|
163
|
+
NOKOGIRI = true
|
164
|
+
rescue LoadError
|
165
|
+
NOKOGIRI = false
|
193
166
|
end
|
194
167
|
|
195
|
-
|
168
|
+
def test_on_parse_error_custom_rescue_handler_gets_called_for_nokogiri
|
169
|
+
return skip('nokogiri not available - test skipped !') unless NOKOGIRI
|
196
170
|
|
197
|
-
|
198
|
-
|
171
|
+
backend = ActiveSupport::XmlMini.backend
|
172
|
+
begin
|
173
|
+
ActiveSupport::XmlMini.backend = 'Nokogiri'
|
174
|
+
post "/parse_with_nokogiri_rescue_block", "<cicinbrus> <name>Ferko</name>", 'CONTENT_TYPE' => 'application/xml'
|
175
|
+
assert_response 505
|
176
|
+
ensure
|
177
|
+
ActiveSupport::XmlMini.backend = backend
|
199
178
|
end
|
179
|
+
end if Rails.version >= '2.3'
|
180
|
+
|
181
|
+
private
|
182
|
+
|
183
|
+
def skip(message = nil)
|
184
|
+
super
|
185
|
+
end
|
186
|
+
|
187
|
+
def assert_xml_parse_exception(error)
|
188
|
+
assert_instance_of REXML::ParseException, error
|
189
|
+
end
|
200
190
|
|
201
191
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,62 +1,90 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
|
3
|
-
require 'test/unit'
|
2
|
+
require 'bundler/setup' rescue nil
|
4
3
|
|
5
4
|
# enable testing with different version of rails via argv :
|
6
|
-
# ruby request_exception_handler_test.rb RAILS_VERSION=2.
|
7
|
-
|
5
|
+
# ruby request_exception_handler_test.rb RAILS_VERSION=2.3.18
|
8
6
|
version =
|
9
7
|
if ARGV.find { |opt| /RAILS_VERSION=([\d\.]+)/ =~ opt }
|
10
8
|
$~[1]
|
11
9
|
else
|
12
|
-
# rake test RAILS_VERSION=2.
|
13
|
-
ENV['RAILS_VERSION']
|
10
|
+
ENV['RAILS_VERSION'] # rake test RAILS_VERSION=3.2.18
|
14
11
|
end
|
15
12
|
|
16
13
|
if version
|
17
14
|
RAILS_VERSION = version
|
18
|
-
gem 'activesupport', "
|
19
|
-
|
20
|
-
gem '
|
21
|
-
#gem 'actionmailer', "= #{RAILS_VERSION}"
|
22
|
-
gem 'rails', "= #{RAILS_VERSION}"
|
15
|
+
gem 'activesupport', "#{RAILS_VERSION}"
|
16
|
+
gem 'actionpack', "#{RAILS_VERSION}"
|
17
|
+
gem 'rails', "#{RAILS_VERSION}"
|
23
18
|
else
|
24
19
|
gem 'activesupport'
|
25
|
-
#gem 'activerecord'
|
26
20
|
gem 'actionpack'
|
27
|
-
#gem 'actionmailer'
|
28
21
|
gem 'rails'
|
22
|
+
end unless defined? Bundler
|
23
|
+
|
24
|
+
require 'rails/version'
|
25
|
+
puts "emulating Rails.version = #{Rails::VERSION::STRING}"
|
26
|
+
|
27
|
+
if Rails::VERSION::MAJOR < 4
|
28
|
+
gem 'test-unit' rescue nil
|
29
|
+
begin
|
30
|
+
require 'test/unit'
|
31
|
+
rescue LoadError
|
32
|
+
gem 'minitest'
|
33
|
+
require 'minitest/unit'
|
34
|
+
MiniTest::Unit.autorun
|
35
|
+
end
|
36
|
+
else
|
37
|
+
gem 'minitest'
|
29
38
|
end
|
30
39
|
|
40
|
+
begin
|
41
|
+
require 'iconv'
|
42
|
+
rescue LoadError
|
43
|
+
begin
|
44
|
+
require 'active_support/inflector'
|
45
|
+
rescue LoadError
|
46
|
+
$LOADED_FEATURES << 'iconv.rb'
|
47
|
+
require 'active_support/inflector'
|
48
|
+
end
|
49
|
+
end if Rails::VERSION::MAJOR < 3
|
31
50
|
require 'active_support'
|
32
51
|
require 'active_support/test_case'
|
33
52
|
require 'action_controller'
|
34
53
|
require 'action_controller/test_case'
|
35
54
|
|
36
|
-
require 'rails/version'
|
37
|
-
puts "emulating Rails.version = #{Rails::VERSION::STRING}"
|
38
|
-
|
39
55
|
require 'action_controller/integration' if Rails::VERSION::MAJOR < 3
|
40
56
|
require 'action_controller/session_management' if Rails::VERSION::MAJOR < 3
|
41
57
|
require 'action_dispatch' if Rails::VERSION::MAJOR >= 3
|
42
58
|
require 'action_dispatch/routing' if Rails::VERSION::MAJOR >= 3
|
43
59
|
|
60
|
+
begin
|
61
|
+
require 'action_dispatch/testing/integration'
|
62
|
+
IntegrationTest = ActionDispatch::IntegrationTest
|
63
|
+
rescue LoadError
|
64
|
+
IntegrationTest = ActionController::IntegrationTest
|
65
|
+
end
|
66
|
+
|
44
67
|
if Rails::VERSION::MAJOR >= 3
|
45
68
|
ActiveSupport::Deprecation.behavior = :stderr
|
46
69
|
else
|
47
70
|
ActiveSupport::Deprecation.debug = true
|
48
71
|
end
|
49
72
|
|
50
|
-
if Rails::VERSION::MAJOR >=
|
73
|
+
if Rails::VERSION::MAJOR >= 4
|
51
74
|
require 'rails'
|
52
75
|
# a minimal require 'rails/all' :
|
53
|
-
require
|
54
|
-
require
|
76
|
+
require 'action_controller/railtie'
|
77
|
+
require 'rails/test_help'
|
78
|
+
elsif Rails::VERSION::MAJOR >= 3
|
79
|
+
require 'rails'
|
80
|
+
# a minimal require 'rails/all' :
|
81
|
+
require 'action_controller/railtie'
|
82
|
+
require 'rails/test_unit/railtie'
|
55
83
|
require 'rails/test_help'
|
56
84
|
else
|
57
85
|
module Rails
|
58
86
|
class << self
|
59
|
-
|
87
|
+
|
60
88
|
def initialized?
|
61
89
|
@initialized || false
|
62
90
|
end
|
@@ -100,7 +128,7 @@ else
|
|
100
128
|
def public_path=(path)
|
101
129
|
@@public_path = path
|
102
130
|
end
|
103
|
-
|
131
|
+
|
104
132
|
end
|
105
133
|
end
|
106
134
|
end
|
@@ -109,7 +137,7 @@ silence_warnings { RAILS_ROOT = File.expand_path( File.dirname(__FILE__) ) }
|
|
109
137
|
|
110
138
|
# Make double-sure the RAILS_ENV is set to test,
|
111
139
|
# so fixtures are loaded to the right database
|
112
|
-
silence_warnings { RAILS_ENV =
|
140
|
+
silence_warnings { RAILS_ENV = 'test' }
|
113
141
|
|
114
142
|
Rails.backtrace_cleaner.remove_silencers! if Rails.backtrace_cleaner
|
115
143
|
|
@@ -130,25 +158,35 @@ if ActionController::Base.respond_to? :session_options # Rails 2.x
|
|
130
158
|
ActionController::Base.session_options[:secret] = 'x' * 30
|
131
159
|
|
132
160
|
else # since Rails 3.0.0 :
|
133
|
-
|
161
|
+
|
134
162
|
module RequestExceptionHandlerTest
|
135
|
-
|
136
|
-
|
163
|
+
|
164
|
+
class Application < Rails::Application; end
|
165
|
+
|
166
|
+
Application.configure do
|
167
|
+
if config.respond_to?(:secret_key_base=)
|
168
|
+
config.secret_key_base = 'x' * 30
|
169
|
+
else
|
170
|
+
config.secret_token = 'x' * 30
|
171
|
+
end
|
172
|
+
config.cache_classes = true if config.respond_to?(:cache_classes=)
|
173
|
+
config.eager_load = false if config.respond_to?(:eager_load=)
|
174
|
+
config.action_controller.allow_forgery_protection = false
|
175
|
+
config.active_support.deprecation = :stderr
|
137
176
|
end
|
138
|
-
end
|
139
|
-
|
140
|
-
# Initialize the rails application
|
141
|
-
RequestExceptionHandlerTest::Application.initialize!
|
142
177
|
|
143
|
-
|
178
|
+
# Since 4.0 only DEFAULT_PARSERS = { Mime::JSON => :json } is setup by default
|
179
|
+
unless ActionDispatch::ParamsParser::DEFAULT_PARSERS[ Mime::XML ]
|
180
|
+
ActionDispatch::ParamsParser::DEFAULT_PARSERS[ Mime::XML ] = Proc.new do
|
181
|
+
|raw_post| ( Hash.from_xml(raw_post) || {} ).with_indifferent_access
|
182
|
+
end
|
183
|
+
end if defined? ActionDispatch::ParamsParser::DEFAULT_PARSERS
|
144
184
|
|
145
|
-
|
185
|
+
Application.initialize!
|
146
186
|
|
147
|
-
def setup_fixtures
|
148
|
-
return nil # Rails 3 load hooks !
|
149
187
|
end
|
150
|
-
|
188
|
+
|
151
189
|
end
|
152
190
|
|
153
|
-
$LOAD_PATH.unshift File.
|
191
|
+
$LOAD_PATH.unshift File.expand_path('../lib', File.dirname(__FILE__))
|
154
192
|
require 'request_exception_handler'
|
metadata
CHANGED
@@ -1,99 +1,84 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: request_exception_handler
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: "0.4"
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
8
|
-
|
6
|
+
authors:
|
7
|
+
- Karol Bucek
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
prerelease: false
|
47
|
-
type: :development
|
48
|
-
description: a rails hook that allows one to handle request parameter parsing exceptions (invalid XML, JSON) with a rescue block
|
49
|
-
email:
|
50
|
-
- self@kares.org
|
11
|
+
date: 2014-06-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: actionpack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 10.3.2
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 10.3.2
|
41
|
+
description: rails hook that allows one to handle request parameter parsing exceptions
|
42
|
+
(e.g. invalid JSON) with a rescue block
|
43
|
+
email:
|
44
|
+
- self@kares.org
|
51
45
|
executables: []
|
52
|
-
|
53
46
|
extensions: []
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
47
|
+
extra_rdoc_files:
|
48
|
+
- README.md
|
49
|
+
files:
|
50
|
+
- LICENSE
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- lib/request_exception_handler.rb
|
54
|
+
- test/_test-unit-rails4.rb
|
55
|
+
- test/request_exception_handler_test.rb
|
56
|
+
- test/test_helper.rb
|
64
57
|
homepage: http://github.com/kares/request_exception_handler
|
65
|
-
licenses:
|
66
|
-
|
58
|
+
licenses:
|
59
|
+
- Apache-2.0
|
60
|
+
metadata: {}
|
67
61
|
post_install_message:
|
68
62
|
rdoc_options: []
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
|
-
requirements:
|
84
|
-
- - ">="
|
85
|
-
- !ruby/object:Gem::Version
|
86
|
-
hash: 2
|
87
|
-
segments:
|
88
|
-
- 0
|
89
|
-
version: "0"
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
90
75
|
requirements: []
|
91
|
-
|
92
76
|
rubyforge_project: "[none]"
|
93
|
-
rubygems_version:
|
77
|
+
rubygems_version: 2.2.2
|
94
78
|
signing_key:
|
95
|
-
specification_version:
|
96
|
-
summary: handler for all request (parsing) related exceptions
|
97
|
-
test_files:
|
98
|
-
|
99
|
-
|
79
|
+
specification_version: 4
|
80
|
+
summary: a handler for all request (parsing) related exceptions
|
81
|
+
test_files:
|
82
|
+
- test/test_helper.rb
|
83
|
+
- test/_test-unit-rails4.rb
|
84
|
+
- test/request_exception_handler_test.rb
|