lib/moysklad/client/errors.rb in moysklad-0.2.1 vs lib/moysklad/client/errors.rb in moysklad-0.3.0

- old
+ new

@@ -1,25 +1,46 @@ class Moysklad::Client class Errors def self.build res - Moysklad.logger.warn "Moyskad::Client: #{res.status}: #{res.env.url.to_s}\n#{res.body}" + body = res.body.force_encoding('utf-8') + content_type = res.headers['content-type'] + if content_type.start_with? 'application/json' + # ok + elsif content_type.start_with? 'text/html' + raise HtmlParsedError, body + else + raise UnknownError, body + end + + # Encoding::UndefinedConversionError + # "\xD0" from ASCII-8BIT to UTF-8 + begin + body = JSON.parse body + Moysklad.logger.debug "Moysklad::Client: #{res.status}: #{res.headers}, #{res.env.url.to_s}\n#{body}" + rescue Encoding::UndefinedConversionError => err + Moysklad.logger.error "#{err}" + rescue JSON::ParserError => err + Moysklad.logger.error "#{err}: #{res.headers}, body:#{body}" + raise ParsingError, body + end + case res.status - when 401 - raise UnauthorizedError.new res + when 401 + raise UnauthorizedError.new body when 403 - raise ResourceForbidden.new res - when 404 - raise NoResourceFound.new res.body - when 405 - raise MethodNotAllowedError.new res + raise ResourceForbidden.new body + when 404 + raise NoResourceFound.new body + when 405, 412 + raise MethodNotAllowedError.new body when 500 - raise InternalServerError.new res + raise InternalServerError.new body when 502 - raise BadGatewayError.new res - else - raise ParsedError.new res + raise BadGatewayError.new body + else + raise JsonParsedError.new body end end end end @@ -30,66 +51,75 @@ def initialize mess @message = mess end def to_s - message + message.to_s.encode('utf-8') + # <?xml version="1.0" encoding="UTF-8"?> <error> <uid>kiiiosk@wannabemoscow</uid> <moment>20150609112728449</moment> <message>������������ ���� ���������� �������� ������������.</message> </error> + rescue Encoding::CompatibilityError + message.to_s.force_encoding('cp1251').encode('utf-8') end end + class ParsingError < Error; end + class UnknownError < Error; end + class NoResourceFound < Error; end + class JsonParsedError < Error + def initialize result + super result.to_json + end + + attr_reader :error + end + class HtmlParsedError < Error - def initialize res - @result = res - @message = "[#{res.status}] #{parse_title res.body}" + def initialize body + @message = parse_title body end private def parse_title body - doc = Nokogiri::HTML body - # у ResourceForbidden есть <u> - # у wrong_password <u> несколько - # Можно ошибку разбирать более грамотно по свойствам type, message, description: http://i.gyazo.com/e9d5d08bd610882d87f39d9002cdf25a.png - [doc.css('body').css('h1').text,doc.css('body').css('u').to_a.map(&:text).compact.last].join('; ') + Nokogiri::HTML(body).css('body').text rescue => err - Moysklad.logger.debug "Moyskad::Client parse error #{err}: #{body}" + Moysklad.logger.debug "Moysklad::Client parse error #{err}: #{body}" body.force_encoding('utf-8') end end - class MethodNotAllowedError < HtmlParsedError + class MethodNotAllowedError < JsonParsedError end - class UnauthorizedError < HtmlParsedError + class UnauthorizedError < JsonParsedError end - class ResourceForbidden < HtmlParsedError + class ResourceForbidden < JsonParsedError end class ParsedError < Error def initialize result @status = result.status @result = result case result.headers['content-type'] - + when /application\/xml/ @error = Moysklad::Entities::Error.parse result.body @message = @error.message when /text\/html/ - doc = Nokogiri::HTML body + doc = Nokogiri::HTML result.body @message = doc.css('body').css('h1').text else raise "Unknown content-type #{result.headers['content-type']} to parse error #{result.body}" end rescue => err - @message = "error in init #{err}: #{result.body}" + @message = "error in init #{err}: #{result}" end attr_reader :error end - class BadGatewayError < HtmlParsedError; end - class InternalServerError < ParsedError; end + class BadGatewayError < JsonParsedError; end + class InternalServerError < JsonParsedError; end end