File tree Expand file tree Collapse file tree 5 files changed +77
-4
lines changed
Expand file tree Collapse file tree 5 files changed +77
-4
lines changed Original file line number Diff line number Diff line change @@ -168,6 +168,15 @@ class Twitter::API < Grape::API
168168end
169169```
170170
171+ class Twitter::API < Grape::API
172+ rescue_from ArgumentError do |e|
173+ Rack::Response.new([ "ArgumentError: #{e.message}" ], 500)
174+ end
175+ rescue_from NotImplementedError do |e|
176+ Rack::Response.new([ "NotImplementedError: #{e.message}" ], 500)
177+ end
178+ end
179+
171180## Writing Tests
172181
173182You can test a Grape API with RSpec. Tests make HTTP requests, therefore they must go into the ` spec/request ` group. You may want your API code to go into ` app/api ` - you can match that layout under ` spec ` by adding the following in ` spec/spec_helper.rb ` .
Original file line number Diff line number Diff line change @@ -52,6 +52,22 @@ def set(key, value)
5252 @settings . last [ key . to_sym ] = value
5353 end
5454
55+ # Add to a configuration value for this
56+ # namespace.
57+ #
58+ # @param key [Symbol] The key of the configuration variable.
59+ # @param value [Object] The value to which to set the configuration variable.
60+ def add ( key , value )
61+ current = @settings . last [ key . to_sym ]
62+ if current . is_a? ( Array )
63+ current . concat ( value )
64+ elsif current . is_a? ( Hash )
65+ current . merge! ( value )
66+ else
67+ @settings . last [ key . to_sym ] = value
68+ end
69+ end
70+
5571 # Define a root URL prefix for your entire
5672 # API.
5773 def prefix ( prefix = nil )
@@ -122,12 +138,12 @@ def default_error_status(new_status = nil)
122138 def rescue_from ( *args , &block )
123139 if block_given?
124140 args . each do |arg |
125- set ( :rescue_handlers , { arg => block } )
141+ add ( :rescue_handlers , { arg => block } )
126142 end
127143 end
128- set ( :rescue_options , args . pop ) if args . last . is_a? ( Hash )
144+ add ( :rescue_options , args . pop ) if args . last . is_a? ( Hash )
129145 set ( :rescue_all , true ) and return if args . include? ( :all )
130- set ( :rescued_errors , args )
146+ add ( :rescued_errors , args )
131147 end
132148
133149 # Add helper methods that will be accessible from any
Original file line number Diff line number Diff line change 11require 'multi_json'
2+ require 'multi_xml'
23
34module Grape
45 module Middleware
@@ -54,9 +55,11 @@ module Formats
5455 FORMATTERS = {
5556 :json => :encode_json ,
5657 :txt => :encode_txt ,
58+ :xml => :encode_xml
5759 }
5860 PARSERS = {
59- :json => :decode_json
61+ :json => :decode_json ,
62+ :xml => :decode_xml
6063 }
6164
6265 def formatters
@@ -120,6 +123,14 @@ def encode_json(object)
120123 def encode_txt ( object )
121124 object . respond_to? ( :to_txt ) ? object . to_txt : object . to_s
122125 end
126+
127+ def decode_xml ( object )
128+ MultiXml . parse ( object )
129+ end
130+
131+ def encode_xml ( object )
132+ object . respond_to? ( :to_xml ) ? object . to_xml : object . to_s
133+ end
123134 end
124135
125136 end
Original file line number Diff line number Diff line change @@ -743,6 +743,28 @@ class ConnectionError < RuntimeError; end
743743 last_response . status . should eql 500
744744 last_response . body . should == 'rescued from ConnectionError'
745745 end
746+ it 'should rescue multiple specific errors' do
747+ class ConnectionError < RuntimeError ; end
748+ class DatabaseError < RuntimeError ; end
749+ subject . rescue_from ConnectionError do |e |
750+ rack_response ( "rescued from #{ e . class . name } " , 500 )
751+ end
752+ subject . rescue_from DatabaseError do |e |
753+ rack_response ( "rescued from #{ e . class . name } " , 500 )
754+ end
755+ subject . get '/connection' do
756+ raise ConnectionError
757+ end
758+ subject . get '/database' do
759+ raise DatabaseError
760+ end
761+ get '/connection'
762+ last_response . status . should eql 500
763+ last_response . body . should == 'rescued from ConnectionError'
764+ get '/database'
765+ last_response . status . should eql 500
766+ last_response . body . should == 'rescued from DatabaseError'
767+ end
746768 it 'should not rescue a different error' do
747769 class CommunicationError < RuntimeError ; end
748770 subject . rescue_from RuntimeError do |e |
Original file line number Diff line number Diff line change @@ -35,6 +35,17 @@ def serializable_hash
3535
3636 subject . call ( { 'PATH_INFO' => '/somewhere' } ) . last . each { |b | b . should == '{"abc":"def"}' }
3737 end
38+
39+ it 'should call #to_xml if the content type is xml' do
40+ @body = "string"
41+ @body . instance_eval do
42+ def to_xml
43+ "<bar/>"
44+ end
45+ end
46+
47+ subject . call ( { 'PATH_INFO' => '/somewhere.xml' } ) . last . each { |b | b . should == '<bar/>' }
48+ end
3849 end
3950
4051 context 'detection' do
@@ -130,6 +141,10 @@ def serializable_hash
130141 subject . env [ 'rack.request.form_hash' ] [ 'is_boolean' ] . should be_true
131142 subject . env [ 'rack.request.form_hash' ] [ 'string' ] . should == 'thing'
132143 end
144+ it 'should parse the body from an xml POST/PUT and put the contents into rack.request.from_hash' do
145+ subject . call ( { 'PATH_INFO' => '/info.xml' , 'Accept' => 'application/xml' , 'rack.input' => StringIO . new ( '<thing><name>Test</name></thing>' ) } )
146+ subject . env [ 'rack.request.form_hash' ] [ 'thing' ] [ 'name' ] . should == 'Test'
147+ end
133148 it 'should be able to fail gracefully if the body is regular POST content' do
134149 subject . call ( { 'PATH_INFO' => '/info' , 'Accept' => 'application/json' , 'rack.input' => StringIO . new ( 'name=Other+Test+Thing' ) } )
135150 subject . env [ 'rack.request.form_hash' ] . should be_nil
You can’t perform that action at this time.
0 commit comments