Skip to content

Commit cc03459

Browse files
committed
Allow specifying headers in error.
1 parent 608191e commit cc03459

File tree

4 files changed

+34
-30
lines changed

4 files changed

+34
-30
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Next Release
77
* [#511](https://github.com/intridea/grape/pull/511): Add `required` option for OAuth2 middleware - [@bcm](https://github.com/bcm).
88
* [#520](https://github.com/intridea/grape/pull/520): Use `default_error_status` to specify the default status code returned from `error!` - [@salimane](https://github.com/salimane).
99
* [#525](https://github.com/intridea/grape/pull/525): The default status code returned from `error!` has been changed from 403 to 500 - [@dblock](https://github.com/dblock).
10+
* [#526](https://github.com/intridea/grape/pull/526): Allow specifying headers in `error!` - [@dblock](https://github.com/dblock).
1011
* Your contribution here.
1112

1213
#### Fixes

README.md

+21-28
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ the context of recreating parts of the Twitter API.
4141
```ruby
4242
module Twitter
4343
class API < Grape::API
44-
4544
version 'v1', using: :header, vendor: 'twitter'
4645
format :json
4746

@@ -56,7 +55,6 @@ module Twitter
5655
end
5756

5857
resource :statuses do
59-
6058
desc "Return a public timeline."
6159
get :public_timeline do
6260
Status.limit(20)
@@ -111,7 +109,6 @@ module Twitter
111109
authenticate!
112110
current_user.statuses.find(params[:id]).destroy
113111
end
114-
115112
end
116113
end
117114
end
@@ -152,7 +149,7 @@ require 'grape'
152149

153150
class API < Grape::API
154151
get :hello do
155-
{hello: "world"}
152+
{ hello: "world" }
156153
end
157154
end
158155

@@ -303,7 +300,7 @@ The Grape endpoint:
303300

304301
```ruby
305302
post '/statuses' do
306-
Status.create!({ text: params[:text] })
303+
Status.create!(text: params[:text])
307304
end
308305
```
309306

@@ -465,10 +462,10 @@ You can rescue a `Grape::Exceptions::ValidationErrors` and respond with a custom
465462

466463
```ruby
467464
rescue_from Grape::Exceptions::ValidationErrors do |e|
468-
Rack::Response.new({
469-
'status' => e.status,
470-
'message' => e.message,
471-
'errors' => e.errors
465+
Rack::Response.new(
466+
status: e.status,
467+
message: e.message,
468+
errors: e.errors
472469
}.to_json, e.status)
473470
end
474471
```
@@ -480,7 +477,6 @@ The validation errors are grouped by parameter name and can be accessed via ``Gr
480477
Grape supports I18n for parameter-related error messages, but will fallback to English if
481478
translations for the default locale have not been provided. See [en.yml](lib/grape/locale/en.yml) for message keys.
482479

483-
484480
## Headers
485481

486482
Request headers are available through the `headers` helper or from `env` in their original form.
@@ -500,7 +496,13 @@ end
500496
You can set a response header with `header` inside an API.
501497

502498
```ruby
503-
header "X-Robots-Tag", "noindex"
499+
header 'X-Robots-Tag', 'noindex'
500+
```
501+
502+
When raising `error!`, pass additional headers as arguments.
503+
504+
```ruby
505+
error! 'Unauthorized', 401, 'X-Error-Detail' => 'Invalid token.'
504506
```
505507

506508
## Routes
@@ -558,7 +560,6 @@ You can set, get and delete your cookies very simply using `cookies` method.
558560

559561
```ruby
560562
class API < Grape::API
561-
562563
get 'status_count' do
563564
cookies[:status_count] ||= 0
564565
cookies[:status_count] += 1
@@ -568,18 +569,17 @@ class API < Grape::API
568569
delete 'status_count' do
569570
{ status_count: cookies.delete(:status_count) }
570571
end
571-
572572
end
573573
```
574574

575575
Use a hash-based syntax to set more than one value.
576576

577577
```ruby
578578
cookies[:status_count] = {
579-
value: 0,
580-
expires: Time.tomorrow,
581-
domain: '.twitter.com',
582-
path: '/'
579+
value: 0,
580+
expires: Time.tomorrow,
581+
domain: '.twitter.com',
582+
path: '/'
583583
}
584584

585585
cookies[:status_count][:value] +=1
@@ -602,11 +602,11 @@ cookies.delete :status_count, path: '/'
602602
You can redirect to a new url temporarily (302) or permanently (301).
603603

604604
```ruby
605-
redirect "/statuses"
605+
redirect '/statuses'
606606
```
607607

608608
```ruby
609-
redirect "/statuses", permanent: true
609+
redirect '/statuses', permanent: true
610610
```
611611

612612
## Allowed Methods
@@ -617,13 +617,11 @@ behavior with `do_not_route_head!`.
617617

618618
``` ruby
619619
class API < Grape::API
620-
621620
do_not_route_head!
622621

623622
get '/example' do
624623
# only responds to GET
625624
end
626-
627625
end
628626
```
629627

@@ -633,7 +631,6 @@ include an "Allow" header listing the supported methods.
633631

634632
```ruby
635633
class API < Grape::API
636-
637634
get '/rt_count' do
638635
{ rt_count: current_user.rt_count }
639636
end
@@ -645,7 +642,6 @@ class API < Grape::API
645642
current_user.rt_count += params[:value].to_i
646643
{ rt_count: current_user.rt_count }
647644
end
648-
649645
end
650646
```
651647

@@ -678,14 +674,14 @@ curl -X DELETE -v http://localhost:3000/rt_count/
678674
You can abort the execution of an API method by raising errors with `error!`.
679675

680676
```ruby
681-
error! "Access Denied", 401
677+
error! 'Access Denied', 401
682678
```
683679

684680
You can also return JSON formatted objects by raising error! and passing a hash
685681
instead of a message.
686682

687683
```ruby
688-
error!({ "error" => "unexpected error", "detail" => "missing widget" }, 500)
684+
error!({ error: "unexpected error", detail: "missing widget" }, 500)
689685
```
690686

691687
### Default Error HTTP Status Code
@@ -1365,7 +1361,6 @@ Create `config/initializers/reload_api.rb`.
13651361

13661362
```ruby
13671363
if Rails.env.development?
1368-
13691364
ActiveSupport::Dependencies.explicitly_unloadable_constants << "Twitter::API"
13701365

13711366
api_files = Dir["#{Rails.root}/app/api/**/*.rb"]
@@ -1375,13 +1370,11 @@ if Rails.env.development?
13751370
ActionDispatch::Callbacks.to_prepare do
13761371
api_reloader.execute_if_updated
13771372
end
1378-
13791373
end
13801374
```
13811375

13821376
See [StackOverflow #3282655](http://stackoverflow.com/questions/3282655/ruby-on-rails-3-reload-lib-directory-for-each-request/4368838#4368838) for more information.
13831377

1384-
13851378
## Performance Monitoring
13861379

13871380
Grape integrates with NewRelic via the

lib/grape/endpoint.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,9 @@ def version
203203
#
204204
# @param message [String] The message to display.
205205
# @param status [Integer] the HTTP Status Code. Defaults to default_error_status, 500 if not set.
206-
def error!(message, status = nil)
206+
def error!(message, status = nil, headers = nil)
207207
status = settings[:default_error_status] unless status
208-
throw :error, message: message, status: status
208+
throw :error, message: message, status: status, headers: headers
209209
end
210210

211211
# Redirect to a new url.

spec/grape/endpoint_spec.rb

+10
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,16 @@ def app
487487
last_response.status.should == 403
488488
last_response.body.should == '{"dude":"rad"}'
489489
end
490+
491+
it 'can specifiy headers' do
492+
subject.get '/hey' do
493+
error!({ 'dude' => 'rad' }, 403, 'X-Custom' => 'value')
494+
end
495+
496+
get '/hey.json'
497+
last_response.status.should == 403
498+
last_response.headers['X-Custom'].should == 'value'
499+
end
490500
end
491501

492502
describe '#redirect' do

0 commit comments

Comments
 (0)