grape 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +15 -15
- data/README.md +21 -2
- data/gemfiles/multi_json.gemfile +1 -1
- data/gemfiles/multi_xml.gemfile +1 -1
- data/gemfiles/rack_1.5.2.gemfile +1 -1
- data/gemfiles/rack_edge.gemfile +1 -1
- data/gemfiles/rails_3.gemfile +1 -1
- data/gemfiles/rails_4.gemfile +1 -1
- data/gemfiles/rails_5.gemfile +1 -1
- data/gemfiles/rails_edge.gemfile +1 -1
- data/lib/grape.rb +2 -0
- data/lib/grape/dsl/inside_route.rb +10 -2
- data/lib/grape/dsl/parameters.rb +2 -3
- data/lib/grape/dsl/settings.rb +14 -2
- data/lib/grape/error_formatter/json.rb +6 -2
- data/lib/grape/error_formatter/txt.rb +8 -3
- data/lib/grape/error_formatter/xml.rb +6 -2
- data/lib/grape/middleware/error.rb +17 -9
- data/lib/grape/middleware/formatter.rb +2 -2
- data/lib/grape/validations/params_scope.rb +11 -2
- data/lib/grape/validations/validators/as.rb +15 -0
- data/lib/grape/validations/validators/base.rb +1 -1
- data/lib/grape/validations/validators/values.rb +8 -3
- data/lib/grape/version.rb +1 -1
- data/pkg/grape-0.19.1.gem +0 -0
- data/spec/grape/api/inherited_helpers_spec.rb +114 -0
- data/spec/grape/api_spec.rb +2 -2
- data/spec/grape/dsl/helpers_spec.rb +19 -0
- data/spec/grape/dsl/parameters_spec.rb +4 -4
- data/spec/grape/middleware/exception_spec.rb +138 -44
- data/spec/grape/middleware/formatter_spec.rb +24 -0
- data/spec/grape/validations/params_scope_spec.rb +76 -0
- data/spec/grape/validations/validators/values_spec.rb +25 -0
- metadata +7 -3
@@ -45,7 +45,7 @@ module Grape
|
|
45
45
|
Rack::Response.new(bodymap, status, headers)
|
46
46
|
end
|
47
47
|
rescue Grape::Exceptions::InvalidFormatter => e
|
48
|
-
throw :error, status: 500, message: e.message
|
48
|
+
throw :error, status: 500, message: e.message, backtrace: e.backtrace, original_exception: e
|
49
49
|
end
|
50
50
|
|
51
51
|
def fetch_formatter(headers, options)
|
@@ -110,7 +110,7 @@ module Grape
|
|
110
110
|
rescue Grape::Exceptions::Base => e
|
111
111
|
raise e
|
112
112
|
rescue StandardError => e
|
113
|
-
throw :error, status: 400, message: e.message
|
113
|
+
throw :error, status: 400, message: e.message, backtrace: e.backtrace, original_exception: e
|
114
114
|
end
|
115
115
|
else
|
116
116
|
env[Grape::Env::API_REQUEST_BODY] = body
|
@@ -46,7 +46,11 @@ module Grape
|
|
46
46
|
parent.should_validate?(parameters)
|
47
47
|
end
|
48
48
|
|
49
|
-
def meets_dependency?(params)
|
49
|
+
def meets_dependency?(params, request_params)
|
50
|
+
if @parent.present? && !@parent.meets_dependency?(@parent.params(request_params), request_params)
|
51
|
+
return false
|
52
|
+
end
|
53
|
+
|
50
54
|
return true unless @dependent_on
|
51
55
|
|
52
56
|
params = params.with_indifferent_access
|
@@ -111,10 +115,15 @@ module Grape
|
|
111
115
|
|
112
116
|
# Adds a parameter declaration to our list of validations.
|
113
117
|
# @param attrs [Array] (see Grape::DSL::Parameters#requires)
|
114
|
-
def push_declared_params(attrs)
|
118
|
+
def push_declared_params(attrs, **opts)
|
115
119
|
if lateral?
|
116
120
|
@parent.push_declared_params(attrs)
|
117
121
|
else
|
122
|
+
if opts && opts[:as]
|
123
|
+
@api.route_setting(:aliased_params, @api.route_setting(:aliased_params) || [])
|
124
|
+
@api.route_setting(:aliased_params) << { attrs.first => opts[:as] }
|
125
|
+
end
|
126
|
+
|
118
127
|
@declared_params.concat attrs
|
119
128
|
end
|
120
129
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Grape
|
2
|
+
module Validations
|
3
|
+
class AsValidator < Base
|
4
|
+
def initialize(attrs, options, required, scope, opts = {})
|
5
|
+
@alias = options
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def validate_param!(attr_name, params)
|
10
|
+
params[@alias] = params[attr_name]
|
11
|
+
params.delete(attr_name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -39,7 +39,7 @@ module Grape
|
|
39
39
|
array_errors = []
|
40
40
|
attributes.each do |resource_params, attr_name|
|
41
41
|
next unless @required || (resource_params.respond_to?(:key?) && resource_params.key?(attr_name))
|
42
|
-
next unless @scope.meets_dependency?(resource_params)
|
42
|
+
next unless @scope.meets_dependency?(resource_params, params)
|
43
43
|
|
44
44
|
begin
|
45
45
|
validate_param!(attr_name, resource_params)
|
@@ -32,7 +32,7 @@ module Grape
|
|
32
32
|
unless check_excepts(param_array)
|
33
33
|
|
34
34
|
raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:values) \
|
35
|
-
unless check_values(param_array)
|
35
|
+
unless check_values(param_array, attr_name)
|
36
36
|
|
37
37
|
raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:values) \
|
38
38
|
if @proc && !param_array.all? { |param| @proc.call(param) }
|
@@ -40,10 +40,15 @@ module Grape
|
|
40
40
|
|
41
41
|
private
|
42
42
|
|
43
|
-
def check_values(param_array)
|
43
|
+
def check_values(param_array, attr_name)
|
44
44
|
values = @values.is_a?(Proc) && @values.arity.zero? ? @values.call : @values
|
45
45
|
return true if values.nil?
|
46
|
-
|
46
|
+
begin
|
47
|
+
return param_array.all? { |param| values.call(param) } if values.is_a? Proc
|
48
|
+
rescue StandardError => e
|
49
|
+
warn "Error '#{e}' raised while validating attribute '#{attr_name}'"
|
50
|
+
return false
|
51
|
+
end
|
47
52
|
param_array.all? { |param| values.include?(param) }
|
48
53
|
end
|
49
54
|
|
data/lib/grape/version.rb
CHANGED
Binary file
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Grape::API::Helpers do
|
4
|
+
let(:user) { 'Miguel Caneo' }
|
5
|
+
let(:id) { '42' }
|
6
|
+
|
7
|
+
module InheritedHelpersSpec
|
8
|
+
class SuperClass < Grape::API
|
9
|
+
helpers do
|
10
|
+
params(:superclass_params) { requires :id, type: String }
|
11
|
+
|
12
|
+
def current_user
|
13
|
+
params[:user]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class OverriddenSubClass < SuperClass
|
19
|
+
params { use :superclass_params }
|
20
|
+
|
21
|
+
helpers do
|
22
|
+
def current_user
|
23
|
+
"#{params[:user]} with id"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
get 'resource' do
|
28
|
+
"#{current_user}: #{params['id']}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class SubClass < SuperClass
|
33
|
+
params { use :superclass_params }
|
34
|
+
|
35
|
+
get 'resource' do
|
36
|
+
"#{current_user}: #{params['id']}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Example < SubClass
|
41
|
+
params { use :superclass_params }
|
42
|
+
|
43
|
+
get 'resource' do
|
44
|
+
"#{current_user}: #{params['id']}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'non overriding subclass' do
|
50
|
+
subject { InheritedHelpersSpec::SubClass }
|
51
|
+
|
52
|
+
def app
|
53
|
+
subject
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'given expected params' do
|
57
|
+
it 'inherits helpers from a superclass' do
|
58
|
+
get '/resource', id: id, user: user
|
59
|
+
expect(last_response.body).to eq("#{user}: #{id}")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'with lack of expected params' do
|
64
|
+
it 'returns missing error' do
|
65
|
+
get '/resource'
|
66
|
+
expect(last_response.body).to eq('id is missing')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'overriding subclass' do
|
72
|
+
subject { InheritedHelpersSpec::OverriddenSubClass }
|
73
|
+
|
74
|
+
def app
|
75
|
+
subject
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'given expected params' do
|
79
|
+
it 'overrides helpers from a superclass' do
|
80
|
+
get '/resource', id: id, user: user
|
81
|
+
expect(last_response.body).to eq("#{user} with id: #{id}")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'with lack of expected params' do
|
86
|
+
it 'returns missing error' do
|
87
|
+
get '/resource'
|
88
|
+
expect(last_response.body).to eq('id is missing')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'example subclass' do
|
94
|
+
subject { InheritedHelpersSpec::Example }
|
95
|
+
|
96
|
+
def app
|
97
|
+
subject
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'given expected params' do
|
101
|
+
it 'inherits helpers from a superclass' do
|
102
|
+
get '/resource', id: id, user: user
|
103
|
+
expect(last_response.body).to eq("#{user}: #{id}")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'with lack of expected params' do
|
108
|
+
it 'returns missing error' do
|
109
|
+
get '/resource'
|
110
|
+
expect(last_response.body).to eq('id is missing')
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/spec/grape/api_spec.rb
CHANGED
@@ -1996,7 +1996,7 @@ XML
|
|
1996
1996
|
before :each do
|
1997
1997
|
module ApiSpec
|
1998
1998
|
class CustomErrorFormatter
|
1999
|
-
def self.call(message, _backtrace, _options, _env)
|
1999
|
+
def self.call(message, _backtrace, _options, _env, _original_exception)
|
2000
2000
|
"message: #{message} @backtrace"
|
2001
2001
|
end
|
2002
2002
|
end
|
@@ -2018,7 +2018,7 @@ XML
|
|
2018
2018
|
before :each do
|
2019
2019
|
module ApiSpec
|
2020
2020
|
class CustomErrorFormatter
|
2021
|
-
def self.call(message, _backtrace, _option, _env)
|
2021
|
+
def self.call(message, _backtrace, _option, _env, _original_exception)
|
2022
2022
|
"message: #{message} @backtrace"
|
2023
2023
|
end
|
2024
2024
|
end
|
@@ -24,6 +24,12 @@ module Grape
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
class Base < Grape::API
|
28
|
+
helpers BooleanParam
|
29
|
+
end
|
30
|
+
|
31
|
+
class Child < Base; end
|
32
|
+
|
27
33
|
describe Helpers do
|
28
34
|
subject { Class.new(HelpersSpec::Dummy) }
|
29
35
|
let(:proc) do
|
@@ -74,6 +80,19 @@ module Grape
|
|
74
80
|
expect(subject.first_mod::Boolean).to eq Virtus::Attribute::Boolean
|
75
81
|
end
|
76
82
|
end
|
83
|
+
|
84
|
+
context 'in child classes' do
|
85
|
+
it 'is available' do
|
86
|
+
klass = Child
|
87
|
+
expect do
|
88
|
+
klass.instance_eval do
|
89
|
+
params do
|
90
|
+
use :requires_toggle_prm
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end.to_not raise_exception
|
94
|
+
end
|
95
|
+
end
|
77
96
|
end
|
78
97
|
end
|
79
98
|
end
|
@@ -15,7 +15,7 @@ module Grape
|
|
15
15
|
@validate_attributes
|
16
16
|
end
|
17
17
|
|
18
|
-
def push_declared_params(
|
18
|
+
def push_declared_params(args, **_opts)
|
19
19
|
@push_declared_params = args
|
20
20
|
end
|
21
21
|
|
@@ -84,7 +84,7 @@ module Grape
|
|
84
84
|
subject.requires :id, type: Integer, desc: 'Identity.'
|
85
85
|
|
86
86
|
expect(subject.validate_attributes_reader).to eq([[:id], { type: Integer, desc: 'Identity.', presence: { value: true, message: nil } }])
|
87
|
-
expect(subject.push_declared_params_reader).to eq([
|
87
|
+
expect(subject.push_declared_params_reader).to eq([:id])
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
@@ -93,7 +93,7 @@ module Grape
|
|
93
93
|
subject.optional :id, type: Integer, desc: 'Identity.'
|
94
94
|
|
95
95
|
expect(subject.validate_attributes_reader).to eq([[:id], { type: Integer, desc: 'Identity.' }])
|
96
|
-
expect(subject.push_declared_params_reader).to eq([
|
96
|
+
expect(subject.push_declared_params_reader).to eq([:id])
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -102,7 +102,7 @@ module Grape
|
|
102
102
|
subject.with(type: Integer) { subject.optional :id, desc: 'Identity.' }
|
103
103
|
|
104
104
|
expect(subject.validate_attributes_reader).to eq([[:id], { type: Integer, desc: 'Identity.' }])
|
105
|
-
expect(subject.push_declared_params_reader).to eq([
|
105
|
+
expect(subject.push_declared_params_reader).to eq([:id])
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
@@ -50,147 +50,241 @@ describe Grape::Middleware::Error do
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
|
53
|
+
def app
|
54
|
+
subject
|
55
|
+
end
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
context 'with defaults' do
|
58
|
+
subject do
|
59
|
+
Rack::Builder.app do
|
60
|
+
use Spec::Support::EndpointFaker
|
61
|
+
use Grape::Middleware::Error
|
62
|
+
run ExceptionSpec::ExceptionApp
|
63
|
+
end
|
64
|
+
end
|
65
|
+
it 'does not trap errors by default' do
|
66
|
+
expect { get '/' }.to raise_error(RuntimeError, 'rain!')
|
60
67
|
end
|
61
|
-
expect { get '/' }.to raise_error(RuntimeError, 'rain!')
|
62
68
|
end
|
63
69
|
|
64
|
-
context 'with rescue_all
|
65
|
-
|
66
|
-
|
70
|
+
context 'with rescue_all' do
|
71
|
+
subject do
|
72
|
+
Rack::Builder.app do
|
67
73
|
use Spec::Support::EndpointFaker
|
68
74
|
use Grape::Middleware::Error, rescue_all: true
|
69
75
|
run ExceptionSpec::ExceptionApp
|
70
76
|
end
|
77
|
+
end
|
78
|
+
it 'sets the message appropriately' do
|
71
79
|
get '/'
|
72
80
|
expect(last_response.body).to eq('rain!')
|
73
81
|
end
|
74
|
-
|
75
82
|
it 'defaults to a 500 status' do
|
76
|
-
@app ||= Rack::Builder.app do
|
77
|
-
use Spec::Support::EndpointFaker
|
78
|
-
use Grape::Middleware::Error, rescue_all: true
|
79
|
-
run ExceptionSpec::ExceptionApp
|
80
|
-
end
|
81
83
|
get '/'
|
82
84
|
expect(last_response.status).to eq(500)
|
83
85
|
end
|
86
|
+
end
|
84
87
|
|
85
|
-
|
86
|
-
|
88
|
+
context do
|
89
|
+
subject do
|
90
|
+
Rack::Builder.app do
|
87
91
|
use Spec::Support::EndpointFaker
|
88
92
|
use Grape::Middleware::Error, rescue_all: true, default_status: 500
|
89
93
|
run ExceptionSpec::ExceptionApp
|
90
94
|
end
|
95
|
+
end
|
96
|
+
it 'is possible to specify a different default status code' do
|
91
97
|
get '/'
|
92
98
|
expect(last_response.status).to eq(500)
|
93
99
|
end
|
100
|
+
end
|
94
101
|
|
95
|
-
|
96
|
-
|
102
|
+
context do
|
103
|
+
subject do
|
104
|
+
Rack::Builder.app do
|
97
105
|
use Spec::Support::EndpointFaker
|
98
106
|
use Grape::Middleware::Error, rescue_all: true, format: :json
|
99
107
|
run ExceptionSpec::ExceptionApp
|
100
108
|
end
|
109
|
+
end
|
110
|
+
it 'is possible to return errors in json format' do
|
101
111
|
get '/'
|
102
112
|
expect(last_response.body).to eq('{"error":"rain!"}')
|
103
113
|
end
|
114
|
+
end
|
104
115
|
|
105
|
-
|
106
|
-
|
116
|
+
context do
|
117
|
+
subject do
|
118
|
+
Rack::Builder.app do
|
107
119
|
use Spec::Support::EndpointFaker
|
108
120
|
use Grape::Middleware::Error, rescue_all: true, format: :json
|
109
121
|
run ExceptionSpec::ErrorHashApp
|
110
122
|
end
|
123
|
+
end
|
124
|
+
it 'is possible to return hash errors in json format' do
|
111
125
|
get '/'
|
112
126
|
expect(['{"error":"rain!","detail":"missing widget"}',
|
113
127
|
'{"detail":"missing widget","error":"rain!"}']).to include(last_response.body)
|
114
128
|
end
|
129
|
+
end
|
115
130
|
|
116
|
-
|
117
|
-
|
131
|
+
context do
|
132
|
+
subject do
|
133
|
+
Rack::Builder.app do
|
118
134
|
use Spec::Support::EndpointFaker
|
119
135
|
use Grape::Middleware::Error, rescue_all: true, format: :jsonapi
|
120
136
|
run ExceptionSpec::ExceptionApp
|
121
137
|
end
|
138
|
+
end
|
139
|
+
it 'is possible to return errors in jsonapi format' do
|
122
140
|
get '/'
|
123
141
|
expect(last_response.body).to eq('{"error":"rain!"}')
|
124
142
|
end
|
143
|
+
end
|
125
144
|
|
126
|
-
|
127
|
-
|
145
|
+
context do
|
146
|
+
subject do
|
147
|
+
Rack::Builder.app do
|
128
148
|
use Spec::Support::EndpointFaker
|
129
149
|
use Grape::Middleware::Error, rescue_all: true, format: :jsonapi
|
130
150
|
run ExceptionSpec::ErrorHashApp
|
131
151
|
end
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'is possible to return hash errors in jsonapi format' do
|
132
155
|
get '/'
|
133
156
|
expect(['{"error":"rain!","detail":"missing widget"}',
|
134
157
|
'{"detail":"missing widget","error":"rain!"}']).to include(last_response.body)
|
135
158
|
end
|
159
|
+
end
|
136
160
|
|
137
|
-
|
138
|
-
|
161
|
+
context do
|
162
|
+
subject do
|
163
|
+
Rack::Builder.app do
|
139
164
|
use Spec::Support::EndpointFaker
|
140
165
|
use Grape::Middleware::Error, rescue_all: true, format: :xml
|
141
166
|
run ExceptionSpec::ExceptionApp
|
142
167
|
end
|
168
|
+
end
|
169
|
+
it 'is possible to return errors in xml format' do
|
143
170
|
get '/'
|
144
171
|
expect(last_response.body).to eq("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<error>\n <message>rain!</message>\n</error>\n")
|
145
172
|
end
|
173
|
+
end
|
146
174
|
|
147
|
-
|
148
|
-
|
175
|
+
context do
|
176
|
+
subject do
|
177
|
+
Rack::Builder.app do
|
149
178
|
use Spec::Support::EndpointFaker
|
150
179
|
use Grape::Middleware::Error, rescue_all: true, format: :xml
|
151
180
|
run ExceptionSpec::ErrorHashApp
|
152
181
|
end
|
182
|
+
end
|
183
|
+
it 'is possible to return hash errors in xml format' do
|
153
184
|
get '/'
|
154
185
|
expect(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<error>\n <detail>missing widget</detail>\n <error>rain!</error>\n</error>\n",
|
155
186
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<error>\n <error>rain!</error>\n <detail>missing widget</detail>\n</error>\n"]).to include(last_response.body)
|
156
187
|
end
|
188
|
+
end
|
157
189
|
|
158
|
-
|
159
|
-
|
190
|
+
context do
|
191
|
+
subject do
|
192
|
+
Rack::Builder.app do
|
160
193
|
use Spec::Support::EndpointFaker
|
161
|
-
use Grape::Middleware::Error,
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
194
|
+
use Grape::Middleware::Error,
|
195
|
+
rescue_all: true,
|
196
|
+
format: :custom,
|
197
|
+
error_formatters: {
|
198
|
+
custom: lambda do |message, _backtrace, _options, _env, _original_exception|
|
199
|
+
{ custom_formatter: message }.inspect
|
200
|
+
end
|
201
|
+
}
|
168
202
|
run ExceptionSpec::ExceptionApp
|
169
203
|
end
|
204
|
+
end
|
205
|
+
it 'is possible to specify a custom formatter' do
|
170
206
|
get '/'
|
171
207
|
expect(last_response.body).to eq('{:custom_formatter=>"rain!"}')
|
172
208
|
end
|
209
|
+
end
|
173
210
|
|
174
|
-
|
175
|
-
|
211
|
+
context do
|
212
|
+
subject do
|
213
|
+
Rack::Builder.app do
|
176
214
|
use Spec::Support::EndpointFaker
|
177
215
|
use Grape::Middleware::Error
|
178
216
|
run ExceptionSpec::AccessDeniedApp
|
179
217
|
end
|
218
|
+
end
|
219
|
+
it 'does not trap regular error! codes' do
|
180
220
|
get '/'
|
181
221
|
expect(last_response.status).to eq(401)
|
182
222
|
end
|
223
|
+
end
|
183
224
|
|
184
|
-
|
185
|
-
|
225
|
+
context do
|
226
|
+
subject do
|
227
|
+
Rack::Builder.app do
|
186
228
|
use Spec::Support::EndpointFaker
|
187
229
|
use Grape::Middleware::Error, rescue_all: false
|
188
230
|
run ExceptionSpec::CustomErrorApp
|
189
231
|
end
|
190
|
-
|
232
|
+
end
|
233
|
+
it 'responds to custom Grape exceptions appropriately' do
|
191
234
|
get '/'
|
192
235
|
expect(last_response.status).to eq(400)
|
193
236
|
expect(last_response.body).to eq('failed validation')
|
194
237
|
end
|
195
238
|
end
|
239
|
+
|
240
|
+
context 'with rescue_options :backtrace and :exception set to true' do
|
241
|
+
subject do
|
242
|
+
Rack::Builder.app do
|
243
|
+
use Spec::Support::EndpointFaker
|
244
|
+
use Grape::Middleware::Error,
|
245
|
+
rescue_all: true,
|
246
|
+
format: :json,
|
247
|
+
rescue_options: { backtrace: true, original_exception: true }
|
248
|
+
run ExceptionSpec::ExceptionApp
|
249
|
+
end
|
250
|
+
end
|
251
|
+
it 'is possible to return the backtrace and the original exception in json format' do
|
252
|
+
get '/'
|
253
|
+
expect(last_response.body).to include('error', 'rain!', 'backtrace', 'original_exception', 'RuntimeError')
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context do
|
258
|
+
subject do
|
259
|
+
Rack::Builder.app do
|
260
|
+
use Spec::Support::EndpointFaker
|
261
|
+
use Grape::Middleware::Error,
|
262
|
+
rescue_all: true,
|
263
|
+
format: :xml,
|
264
|
+
rescue_options: { backtrace: true, original_exception: true }
|
265
|
+
run ExceptionSpec::ExceptionApp
|
266
|
+
end
|
267
|
+
end
|
268
|
+
it 'is possible to return the backtrace and the original exception in xml format' do
|
269
|
+
get '/'
|
270
|
+
expect(last_response.body).to include('error', 'rain!', 'backtrace', 'original-exception', 'RuntimeError')
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context do
|
275
|
+
subject do
|
276
|
+
Rack::Builder.app do
|
277
|
+
use Spec::Support::EndpointFaker
|
278
|
+
use Grape::Middleware::Error,
|
279
|
+
rescue_all: true,
|
280
|
+
format: :txt,
|
281
|
+
rescue_options: { backtrace: true, original_exception: true }
|
282
|
+
run ExceptionSpec::ExceptionApp
|
283
|
+
end
|
284
|
+
end
|
285
|
+
it 'is possible to return the backtrace and the original exception in txt format' do
|
286
|
+
get '/'
|
287
|
+
expect(last_response.body).to include('error', 'rain!', 'backtrace', 'original exception', 'RuntimeError')
|
288
|
+
end
|
289
|
+
end
|
196
290
|
end
|