blob: af663cf23880899c5ae616ed470dea2662229ed3 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
module Deltacloud
class ErrorResponse < Faraday::Response::Middleware
include Deltacloud::Client::Helpers::Model
# This method tries to parse the error XML from Deltacloud API
# In case there is no error returned in body, it will try to use
# the generic error reporting.
#
# - name -> Deltacloud::Client::+Class+
# - error -> Deltacloud XML error representation
# - message -> Exception message (overiden by error body message if
# present)
#
def client_error(name, error, message=nil)
args = {
:message => message,
:status => error ? error[:status] : '500'
}
# If Deltacloud API sends an error in the response body, parse it.
# Otherwise, when DC API sends just plain text error, use
# it as the exception message.
# If DC API does not send anything back, then fallback to
# the 'message' attribute.
#
if error and !error[:body].empty?
if xml_error?(error)
args.merge! parse_error(error[:body].to_xml.root)
else
args[:message] = error[:body]
end
end
error(name).new(args)
end
def call(env)
@app.call(env).on_complete do |e|
case e[:status].to_s
when '401'
raise client_error(:authentication_error, e,
'Invalid :api_user or :api_password')
when '405'
raise client_error(
:invalid_state, e, 'Resource state does not permit this action'
)
when '404'
raise client_error(:not_found, e, 'Object not found')
when /40\d/
raise client_error(:client_failure, e)
when '500'
raise client_error(:server_error, e)
when '502'
raise client_error(:backend_error, e)
when '501'
raise client_error(:not_supported, e)
end
end
end
private
def xml_error?(error)
error[:body].to_xml.root && error[:body].to_xml.root.name == 'error'
end
# Parse the Deltacloud API error body to Hash
#
def parse_error(body)
args = {}
args[:original_error] = body.to_s
args[:server_backtrace] = body.text_at('backtrace')
args[:message] ||= body.text_at('message')
args[:driver] = body.attr_at('backend', 'driver')
args[:provider] = body.attr_at('backend', 'provider')
args
end
end
end