Skip to content

Commit

Permalink
Allow specifying response headers for errors
Browse files Browse the repository at this point in the history
  • Loading branch information
janko committed Aug 15, 2016
1 parent 56ca9b2 commit 1a8c4af
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 5 deletions.
2 changes: 1 addition & 1 deletion lib/goliath/api.rb
Expand Up @@ -172,7 +172,7 @@ def call(env)

rescue Goliath::Validation::Error => e
env[RACK_EXCEPTION] = e
env[ASYNC_CALLBACK].call(validation_error(e.status_code, e.message))
env[ASYNC_CALLBACK].call(validation_error(e.status_code, e.message, e.headers))

rescue Exception => e
logthis = "#{e.backtrace[0]}: #{e.message} (#{e.class})\n"
Expand Down
2 changes: 1 addition & 1 deletion lib/goliath/rack/validator.rb
Expand Up @@ -39,7 +39,7 @@ def safely(env, headers={})
begin
yield
rescue Goliath::Validation::Error => e
validation_error(e.status_code, e.message, headers)
validation_error(e.status_code, e.message, e.headers.merge(headers))
rescue Exception => e
env.logger.error(e.message)
env.logger.error(e.backtrace.join("\n"))
Expand Down
2 changes: 1 addition & 1 deletion lib/goliath/request.rb
Expand Up @@ -226,7 +226,7 @@ def post_process(results)
# @return [Nil]
def server_exception(e)
if e.is_a?(Goliath::Validation::Error)
status, headers, body = [e.status_code, {}, ('{"error":"%s"}' % e.message)]
status, headers, body = [e.status_code, e.headers, ('{"error":"%s"}' % e.message)]
else
@env[RACK_LOGGER].error("#{e.message}\n#{e.backtrace.join("\n")}")
message = Goliath.env?(:production) ? 'An error happened' : e.message
Expand Down
5 changes: 4 additions & 1 deletion lib/goliath/validation/error.rb
Expand Up @@ -4,6 +4,8 @@ module Validation
class Error < StandardError
# The status code to return from the error handler
attr_accessor :status_code
# The headers to return from the error handler
attr_accessor :headers

# Create a new Goliath::Validation::Error.
#
Expand All @@ -13,9 +15,10 @@ class Error < StandardError
# @param status_code [Integer] The status code to return
# @param message [String] The error message to return
# @return [Goliath::Validation::Error] The Goliath::Validation::Error
def initialize(status_code, message)
def initialize(status_code, message, headers = {})
super(message)
@status_code = status_code
@headers = headers
end
end
end
Expand Down
22 changes: 21 additions & 1 deletion spec/integration/valid_spec.rb
Expand Up @@ -54,7 +54,7 @@ def response(env)

class ValidationErrorInEndpoint < Goliath::API
def response(env)
raise Goliath::Validation::Error.new(420, 'You Must Chill')
raise Goliath::Validation::Error.new(420, 'You Must Chill', {'Foo' => 'Bar'})
end
end

Expand All @@ -66,8 +66,28 @@ def response(env)
get_request({}, err) do |c|
c.response.should == '[:error, "You Must Chill"]'
c.response_header.status.should == 420
c.response_header["Foo"].should == 'Bar'
end
end
end
end

class ValidationErrorWhileParsing < Goliath::API
def on_headers(env, headers)
raise Goliath::Validation::Error.new(420, 'You Must Chill', {'Foo' => 'Bar'})
end
end

describe ValidationErrorWhileParsing do
let(:err) { Proc.new { fail "API request failed" } }

it 'handles Goliath::Validation::Error correctly' do
with_api(ValidationErrorInEndpoint) do
get_request({}, err) do |c|
c.response.should == '[:error, "You Must Chill"]'
c.response_header.status.should == 420
c.response_header["Foo"].should == 'Bar'
end
end
end
end

0 comments on commit 1a8c4af

Please sign in to comment.