Skip to content
Browse files

Merge pull request #43 from robgleeson/patch/01

Add Callbacks#handle_exception.
  • Loading branch information...
2 parents 879209e + bee0b3d commit 5a2200b55b1b9e4f2701310d7e010532ea6d55f0 @seancribbs seancribbs committed
Showing with 76 additions and 10 deletions.
  1. +6 −10 lib/webmachine/decision/fsm.rb
  2. +16 −0 lib/webmachine/resource/callbacks.rb
  3. +54 −0 spec/webmachine/decision/flow_spec.rb
View
16 lib/webmachine/decision/fsm.rb
@@ -37,11 +37,15 @@ def run
rescue MalformedRequest => malformed
Webmachine.render_error(400, request, response, :message => malformed.message)
respond(400)
- rescue => e # Handle all exceptions without crashing the server
- error_response(e, state)
+ rescue Exception => e # Handle all exceptions without crashing the server
+ response.end_state = state
+ code = resource.handle_exception(e)
+ code = (100...600).include?(code) ? (code) : (500)
+ respond(code)
end
private
+
def respond(code, headers={})
response.headers.merge!(headers)
case code
@@ -56,14 +60,6 @@ def respond(code, headers={})
# TODO: add logging/tracing
end
- # Renders a 500 error by capturing the exception information.
- def error_response(exception, state)
- response.error = [exception.message, exception.backtrace].flatten.join("\n ")
- response.end_state = state
- Webmachine.render_error(500, request, response)
- respond(500)
- end
-
end # class FSM
end # module Decision
end # module Webmachine
View
16 lib/webmachine/resource/callbacks.rb
@@ -360,6 +360,22 @@ def generate_etag
# @api callback
def finish_request; end
+ #
+ # This method is called when an exception is raised within a subclass of
+ # {Webmachine::Resource}.
+ #
+ # @param [Exception] e
+ # The exception.
+ #
+ # @return [void]
+ #
+ # @api callback
+ #
+ def handle_exception(e)
+ response.error = [e.message, e.backtrace].flatten.join("\n ")
+ Webmachine.render_error(500, request, response)
+ end
+
# This method is called when verifying the Content-MD5 header
# against the request body. To do your own validation, implement
# it in this callback, returning true or false. To bypass header
View
54 spec/webmachine/decision/flow_spec.rb
@@ -1029,4 +1029,58 @@ def accept_all
end
end
end
+
+ describe "On exception" do
+ context "handle_exception is inherited." do
+ let :resource do
+ resource_with do
+ def to_html
+ raise
+ end
+ end
+ end
+
+ it "calls handle_exception." do
+ resource.should_receive(:handle_exception).with instance_of(RuntimeError)
+ subject.run
+ end
+
+ it "sets the response code to 500." do
+ subject.run
+ response.code.should == 500
+ end
+
+ it "sets the end state properly." do
+ subject.run
+ response.end_state.should == :o18
+ end
+ end
+
+ context "handle_exception is defined." do
+ let :resource do
+ resource_with do
+ def handle_exception(e)
+ response.body = "error"
+ 501
+ end
+
+ def to_html
+ raise
+ end
+ end
+ end
+
+ it "can define a response body." do
+ subject.run
+ response.body.should == "error"
+ end
+
+ it "uses the return value as a response code." do
+ subject.run
+ response.code.should == 501
+ end
+ end
+ end
+
+
end

0 comments on commit 5a2200b

Please sign in to comment.
Something went wrong with that request. Please try again.