# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"). You # may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # or in the "license" file accompanying this file. This file 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. require 'thread' require 'aws/xml_grammar' module AWS module Errors # Base class for the two service error classes: # # * {ClientError} # * {ServerError} # # When interacting with Amazon AWS services, you will sometimes # receive a non-200 level response. These http responses are treated # as errors. # # == Client Errors # # Errors in the three and four hundreds are client errors ({ClientError}). # A client error should not be resent without changes. The body of the # http response (the error #message) should give more information about # the nature of the problem. # # == Server Errors # # A 500 level error typically indicates the service is having an issue. # # Requests that generate service errors are automatically retried with # an exponential backoff. If the service still fails to respond with # a 200 after 3 retries the error is raised. # class Base < StandardError # @return [Http::Request] The low level http request that caused the # error to be raised. attr_reader :http_request # @return [Http::Response] The low level http response from the service # that wrapped the service error. attr_reader :http_response def initialize http_request = nil, http_response = nil, message = nil message ||= http_response.body if http_response @http_request = http_request @http_response = http_response super(message) end end # @private module ExceptionMixinClassMethods def new(*args) e = Base.new(*args) e.extend(self) e end end # Raised when an error occurs as a result of bad client # behavior, most commonly when the parameters passed to a method # are somehow invalid. Other common cases: # # * Throttling errors # * Bad credentials # * No permission to do the requested operation # * Limits exceeded (e.g. too many buckets) # module ClientError extend ExceptionMixinClassMethods end # Raised when an AWS service is unable to handle the request. These # are automatically retired. If after 3 retries the request is still # failing, then the error is raised. module ServerError extend ExceptionMixinClassMethods end # @private module ModeledError # @return [String] The error message given by the AWS service. attr_accessor :message # @return [Integer] The HTTP status code returned by the AWS service. attr_reader :code def initialize(req = nil, resp = nil) if req.kind_of?(String) # makes it easier to test handling of modeled exceptions super(nil, nil, req) @message = req elsif req and resp super(req, resp, message) include_error_type parse_body(resp.body) else super() end end def include_error_type if http_response.status >= 500 extend ServerError else extend ClientError end end def parse_body(body) error_grammar.parse(body, :context => self) end def extract_message(body) error_grammar.parse(body).message end def error_grammar self.class::BASE_ERROR_GRAMMAR end end end end