Commits

Michael Granger committed 48fb08c

Treat exceptions raised from negotiated content blocks as a failed format

Comments (0)

Files changed (3)

lib/strelka/app.rb

 		# Some status codes allow explanatory text to be returned; some forbid it. Append the
 		# message for those that allow one.
 		unless request.verb == :HEAD || response.bodiless?
+			self.log.debug "Writing plain-text response body: %p" % [ message ]
 			response.content_type = 'text/plain'
 			response.puts( message )
 		end

lib/strelka/httpresponse/negotiation.rb

 	def try_content_type_callback( mimetype, callback )
 		self.log.debug "  trying content-type callback %p (%s)" % [ callback, mimetype ]
 
-		new_body = callback.call( mimetype ) or return false
+		new_body = begin
+			callback.call( mimetype )
+		rescue => err
+			self.log.error "  %p raised from the callback for %s: %s" %
+				[ err.class, mimetype, err.message ]
+			return false
+		end
 
 		self.log.debug "  successfully transformed: %p! Setting up response." % [ new_body.class ]
 		stringifiers = Strelka::HTTPResponse::Negotiation.stringifiers

spec/strelka/httpresponse/negotiation_spec.rb

 			}.to raise_error( StandardError, /no known mimetype/i )
 		end
 
+		it "treat exceptions raised from the block as failed transformations" do
+			@req.headers.accept = 'application/json, text/plain; q=0.9'
+
+			@res.for( :json ) do
+				raise "Oops! I fail at JSON!"
+			end
+			@res.for( :text ) do
+				"But I can do plain-text all day long!"
+			end
+
+			@res.negotiated_body.rewind
+			expect( @res.negotiated_body.read ).to eq( "But I can do plain-text all day long!" )
+			expect( @res.content_type ).to eq( 'text/plain' )
+			expect( @res.header_data ).to match( /accept(?!-)/i )
+		end
+
 	end