require 'spec_helper'
require 'active_support/core_ext/hash'
describe Grape::Middleware::Error do
# raises a text exception
class ExceptionApp
class << self
def call(env)
raise "rain!"
end
end
end
# raises a hash error
class ErrorHashApp
class << self
def error!(message, status=403)
throw :error, :message => { :error => message, :detail => "missing widget" }, :status => status
end
def call(env)
error!("rain!", 401)
end
end
end
# raises an error!
class AccessDeniedApp
class << self
def error!(message, status=403)
throw :error, :message => message, :status => status
end
def call(env)
error!("Access Denied", 401)
end
end
end
# raises a custom error
class CustomError < Grape::Exceptions::Base; end
class CustomErrorApp
class << self
def call(env)
raise CustomError, :status => 400, :message => 'failed validation'
end
end
end
def app
@app
end
it 'should not trap errors by default' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error
run ExceptionApp
end
lambda { get '/' }.should raise_error
end
context 'with rescue_all set to true' do
it 'should set the message appropriately' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error, :rescue_all => true
run ExceptionApp
end
get '/'
last_response.body.should == "rain!"
end
it 'should default to a 403 status' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error, :rescue_all => true
run ExceptionApp
end
get '/'
last_response.status.should == 403
end
it 'should be possible to specify a different default status code' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error, :rescue_all => true, :default_status => 500
run ExceptionApp
end
get '/'
last_response.status.should == 500
end
it 'should be possible to return errors in json format' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error, :rescue_all => true, :format => :json
run ExceptionApp
end
get '/'
last_response.body.should == '{"error":"rain!"}'
end
it 'should be possible to return hash errors in json format' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error, :rescue_all => true, :format => :json
run ErrorHashApp
end
get '/'
['{"error":"rain!","detail":"missing widget"}',
'{"detail":"missing widget","error":"rain!"}'].should be_include(last_response.body)
end
it 'should be possible to return errors in xml format' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error, :rescue_all => true, :format => :xml
run ExceptionApp
end
get '/'
last_response.body.should == "\n\n rain!\n\n"
end
it 'should be possible to return hash errors in xml format' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error, :rescue_all => true, :format => :xml
run ErrorHashApp
end
get '/'
["\n\n missing widget\n rain!\n\n",
"\n\n rain!\n missing widget\n\n"].should be_include(last_response.body)
end
it 'should be possible to specify a custom formatter' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error,
:rescue_all => true,
:format => :custom,
:error_formatters => {
:custom => lambda { |message, backtrace, options, env|
{ :custom_formatter => message }.inspect
}
}
run ExceptionApp
end
get '/'
last_response.body.should == '{:custom_formatter=>"rain!"}'
end
it 'should not trap regular error! codes' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error
run AccessDeniedApp
end
get '/'
last_response.status.should == 401
end
it 'should respond to custom Grape exceptions appropriately' do
@app ||= Rack::Builder.app do
use Grape::Middleware::Error, :rescue_all => false
run CustomErrorApp
end
get '/'
last_response.status.should == 400
last_response.body.should == 'failed validation'
end
end
end