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