File tree Expand file tree Collapse file tree 10 files changed +83
-8
lines changed Expand file tree Collapse file tree 10 files changed +83
-8
lines changed Original file line number Diff line number Diff line change 1
1
Next Release
2
2
============
3
3
4
+ * [ #201 ] ( https://github.com/intridea/grape/pull/201 ) : Added custom exceptions to Grape. Updated validations to use ValidationError that can be rescued. - [ @adamgotterer ] ( https://github.com/adamgotterer ) .
4
5
* [ #211 ] ( https://github.com/intridea/grape/pull/211 ) : Updates to validation and coercion: Fix #211 and force order of operations for presence and coercion - [ @adamgotterer ] ( https://github.com/adamgotterer ) .
5
6
* [ #210 ] ( https://github.com/intridea/grape/pull/210 ) : Fix: ` Endpoint#body_params ` causing undefined method 'size' - [ @adamgotterer ] ( https://github.com/adamgotterer ) .
6
7
* [ #201 ] ( https://github.com/intridea/grape/pull/201 ) : Rewritten ` params ` DSL, including support for coercion and validations - [ @schmurfy ] ( https://github.com/schmurfy ) .
Original file line number Diff line number Diff line change @@ -11,6 +11,11 @@ module Grape
11
11
autoload :Cookies , 'grape/cookies'
12
12
autoload :Validations , 'grape/validations'
13
13
14
+ module Exceptions
15
+ autoload :Base , 'grape/exceptions/base'
16
+ end
17
+ autoload :ValidationError , 'grape/exceptions/validation_error'
18
+
14
19
module Middleware
15
20
autoload :Base , 'grape/middleware/base'
16
21
autoload :Prefixer , 'grape/middleware/prefixer'
Original file line number Diff line number Diff line change
1
+ module Grape
2
+ module Exceptions
3
+ class Base < StandardError
4
+ attr_reader :status , :message , :headers
5
+
6
+ def initialize ( args = { } )
7
+ @status = args [ :status ] || nil
8
+ @message = args [ :message ] || nil
9
+ @headers = args [ :headers ] || nil
10
+ end
11
+
12
+ def []( index )
13
+ self . send ( index )
14
+ end
15
+ end
16
+ end
17
+ end
Original file line number Diff line number Diff line change
1
+ require 'grape/exceptions/base'
2
+
3
+ class ValidationError < Grape ::Exceptions ::Base
4
+ end
Original file line number Diff line number Diff line change @@ -44,11 +44,19 @@ def call!(env)
44
44
return @app . call ( @env )
45
45
} )
46
46
rescue Exception => e
47
- raise unless options [ :rescue_all ] || ( options [ :rescued_errors ] || [ ] ) . include? ( e . class )
48
- handler = options [ :rescue_handlers ] [ e . class ] || options [ :rescue_handlers ] [ :all ]
47
+ is_rescuable = rescuable? ( e . class )
48
+ if e . is_a? ( Grape ::Exceptions ::Base ) && !is_rescuable
49
+ handler = lambda { error_response ( e ) }
50
+ else
51
+ raise unless is_rescuable
52
+ handler = options [ :rescue_handlers ] [ e . class ] || options [ :rescue_handlers ] [ :all ]
53
+ end
49
54
handler . nil? ? handle_error ( e ) : self . instance_exec ( e , &handler )
50
55
end
51
-
56
+ end
57
+
58
+ def rescuable? ( klass )
59
+ options [ :rescue_all ] || ( options [ :rescued_errors ] || [ ] ) . include? ( klass )
52
60
end
53
61
54
62
def handle_error ( e )
Original file line number Diff line number Diff line change @@ -12,7 +12,7 @@ def validate_param!(attr_name, params)
12
12
if valid_type? ( new_value )
13
13
params [ attr_name ] = new_value
14
14
else
15
- throw :error , :status => 400 , :message => "invalid parameter: #{ attr_name } "
15
+ raise ValidationError , :status => 400 , :message => "invalid parameter: #{ attr_name } "
16
16
end
17
17
end
18
18
Original file line number Diff line number Diff line change 1
1
module Grape
2
2
module Validations
3
-
4
3
class PresenceValidator < Validator
5
4
def validate_param! ( attr_name , params )
6
5
unless params . has_key? ( attr_name )
7
- throw :error , :status => 400 , :message => "missing parameter: #{ attr_name } "
6
+ raise ValidationError , :status => 400 , :message => "missing parameter: #{ attr_name } "
8
7
end
9
8
end
10
9
end
11
-
12
10
end
13
11
end
Original file line number Diff line number Diff line change @@ -4,7 +4,7 @@ module Validations
4
4
class RegexpValidator < SingleOptionValidator
5
5
def validate_param! ( attr_name , params )
6
6
if params [ attr_name ] && !( params [ attr_name ] . to_s =~ @option )
7
- throw :error , :status => 400 , :message => "invalid parameter: #{ attr_name } "
7
+ raise ValidationError , :status => 400 , :message => "invalid parameter: #{ attr_name } "
8
8
end
9
9
end
10
10
end
Original file line number Diff line number Diff line change @@ -669,6 +669,27 @@ def three
669
669
670
670
lambda { get '/unrescued' } . should raise_error
671
671
end
672
+
673
+ it 'should not re-raise exceptions of type Grape::Exception::Base' do
674
+ class CustomError < Grape ::Exceptions ::Base ; end
675
+ subject . get ( '/custom_exception' ) { raise CustomError }
676
+
677
+ lambda { get '/custom_exception' } . should_not raise_error
678
+ end
679
+
680
+ it 'should rescue custom grape exceptions' do
681
+ class CustomError < Grape ::Exceptions ::Base ; end
682
+ subject . rescue_from CustomError do |e |
683
+ rack_response ( 'New Error' , e . status )
684
+ end
685
+ subject . get '/custom_error' do
686
+ raise CustomError , :status => 400 , :message => 'Custom Error'
687
+ end
688
+
689
+ get '/custom_error'
690
+ last_response . status . should == 400
691
+ last_response . body . should == 'New Error'
692
+ end
672
693
end
673
694
674
695
describe ".rescue_from klass, block" do
Original file line number Diff line number Diff line change @@ -34,6 +34,16 @@ def call(env)
34
34
end
35
35
end
36
36
end
37
+
38
+ # raises a custom error
39
+ class CustomError < Grape ::Exceptions ::Base ; end
40
+ class CustomErrorApp
41
+ class << self
42
+ def call ( env )
43
+ raise CustomError , :status => 400 , :message => 'failed validation'
44
+ end
45
+ end
46
+ end
37
47
38
48
def app
39
49
@app
@@ -116,6 +126,17 @@ def app
116
126
get '/'
117
127
last_response . status . should == 401
118
128
end
129
+
130
+ it 'should respond to custom Grape exceptions appropriately' do
131
+ @app ||= Rack ::Builder . app do
132
+ use Grape ::Middleware ::Error , :rescue_all => false
133
+ run CustomErrorApp
134
+ end
135
+
136
+ get '/'
137
+ last_response . status . should == 400
138
+ last_response . body . should == 'failed validation'
139
+ end
119
140
120
141
end
121
142
end
You can’t perform that action at this time.
0 commit comments