diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c17f18d3..9b0f2660a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ * [#1249](https://github.com/ruby-grape/grape/pull/1249): Don't fail even if invalid type value is passed to default validator - [@namusyaka](https://github.com/namusyaka). * [#1263](https://github.com/ruby-grape/grape/pull/1263): Fix `route :any, '*path'` breaking generated `OPTIONS`, Method Not Allowed routes - [@arempe93](https://github.com/arempe93). * [#1266](https://github.com/ruby-grape/grape/pull/1266): Fix `Allow` header including `OPTIONS` when `do_not_route_options!` is active - [@arempe93](https://github.com/arempe93). +* [#1264](https://github.com/ruby-grape/grape/pull/1264): Unify behavior of default_error_status - [@namusyaka](https://github.com/namusyaka). 0.14.0 (12/07/2015) =================== diff --git a/README.md b/README.md index ec11d2699..125606135 100644 --- a/README.md +++ b/README.md @@ -1612,6 +1612,8 @@ class API < Grape::API end ``` +Of course, `default_error_status` does not depend on the timing of route definition, so mounted application can also use the default error status code. + ### Handling 404 For Grape to handle all the 404s for your API, it can be useful to use a catch-all. diff --git a/UPGRADING.md b/UPGRADING.md index 0f4b32aa3..ccba4bb0c 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -1,6 +1,39 @@ Upgrading Grape =============== +#### Changes to behavior of `default_error_status` + +The `default_error_status` method had been depending on the timing of route definition. + +Currently, the difference of behaviors has been unified. The following code is treated as same meaning. + +```ruby +class A < Grape::API + default_error_status 400 +end + +class API < Grape::API + mount A +end + +A.get '/error' do + error!('error') +end +``` + +```ruby +class B < Grape::API + default_error_status 400 + get '/error' do + error!('error') + end +end + +class API < Grape::API + mount B +end +``` + ### Upgrading to >= 0.15.0 #### Changes to availability of `:with` option of `rescue_from` method diff --git a/lib/grape/dsl/routing.rb b/lib/grape/dsl/routing.rb index 699649c4d..a0d6313a5 100644 --- a/lib/grape/dsl/routing.rb +++ b/lib/grape/dsl/routing.rb @@ -87,6 +87,11 @@ def mount(mounts) change! end + app.endpoints.each do |endpoint| + current_error_status = namespace_inheritable(:default_error_status) || 500 + endpoint.namespace_inheritable(:default_error_status, current_error_status) + end if !app.is_a?(Proc) && app.ancestors.include?(Grape::API) + endpoints << Grape::Endpoint.new( in_setting, method: :any, diff --git a/spec/grape/api_spec.rb b/spec/grape/api_spec.rb index 90349ca89..1b3b56592 100644 --- a/spec/grape/api_spec.rb +++ b/spec/grape/api_spec.rb @@ -1983,6 +1983,37 @@ def self.call(object, _env) get '/exception' expect(last_response.status).to eql 400 end + + context 'with mounted api' do + before do + subject.version 'v1', using: :path + subject.default_error_status 400 + end + + it 'inherits default error status' do + api = Class.new(Grape::API) + subject.mount api + api.get('/error') do + error!('error!') + end + + get '/v1/error' + expect(last_response.status).to eql 400 + expect(last_response.body).to eq('error!') + end + + it 'inherits default error status even if target route is registered before mounting self' do + api = Class.new(Grape::API) + api.get('/error') do + error!('error!') + end + subject.mount api + + get '/v1/error' + expect(last_response.status).to eql 400 + expect(last_response.body).to eq('error!') + end + end end context 'http_codes' do