Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request webmachine#43 from robgleeson/patch/01
Add Callbacks#handle_exception.
  • Loading branch information
seancribbs committed Apr 18, 2012
2 parents 879209e + bee0b3d commit 5a2200b
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 10 deletions.
16 changes: 6 additions & 10 deletions lib/webmachine/decision/fsm.rb
Expand Up @@ -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
Expand All @@ -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
16 changes: 16 additions & 0 deletions lib/webmachine/resource/callbacks.rb
Expand Up @@ -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
Expand Down
54 changes: 54 additions & 0 deletions spec/webmachine/decision/flow_spec.rb
Expand Up @@ -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.