“TypeError:强制转换为Unicode:需要字符串或缓冲区”,同时引发异常

时间:2015-08-19 15:29:11

标签: python unicode python-requests python-unicode

我在生产系统上面临一些奇怪的例外:

  

TypeError:强制转换为Unicode:需要字符串或缓冲区,找到InvalidHTTPStatusCode

但我无法在本地重现它。此外,当我登录到生产系统并尝试手动重现错误时,一切正常。

代码

import requests
from requests.exceptions import HTTPError
_session = requests.Session()

class HTTPResponseException(HTTPError):
  def __init__(self, response):
    self.response = response

  def __str__(self):
    return 'HTTP request failed with status code {}.\n' \
           'URL {}\nContent {}\nHeaders {}'.format(
               self.response.status_code,
               self.response.url,
               self.response.content,
               self.response.headers)


class InvalidHTTPStatusCode(HTTPResponseException):
  pass


def get_request(url)
  response = _session.request('get', url)
  if response.status_code != 200
    ex = InvalidHTTPStatusCode(response)
    raise ex

get_request('https://my.server.com/REST/something')

Stacktrace (试图简化它):

File '/my_request.py', line x, in get_request", 
   raise ex", 
TypeError: coercing to Unicode: need string or buffer, InvalidHTTPStatusCode found", 

服务器响应

来自Web服务的错误响应是HTTP 401,正文是包含Unicode字符“×”的HTML代码。

我的问题

我目前不知道为什么raise ex会导致此coercing to Unicode例外。我这行没有Unicode值。我不知何故认为在Python的深处有一些序列化将导致这种异常(由于response.content内的Unicode字符),但这只是猜测。

你知道真正的原因以及如何解决这个问题吗?

环境

  • Ubuntu 14.04.3
  • Python 2.7.9(自编译到单独的目录)
  • 要求2.5.3

2 个答案:

答案 0 :(得分:1)

好的,所以你提出了InvalidHTTPStatusCode。这继承自HTTPResponseException。这有一个__ str__方法,它使用返回的数据格式化非unicode字符串。

简而言之,

    return u'HTTP request failed with status code {}.\n' \
           'URL {}\nContent {}\nHeaders {}'.format(
    ....

(将你添加到字符串的开头。)你在复制它时遇到问题的原因很可能是因为日志记录调用了这个函数,而你不是。我敢打赌,如果你明确地说这个,你可以得到一个类似的例外。

答案 1 :(得分:0)

与此同时,我将实现异常更改为以下代码,该代码似乎解决了响应中 Unicode 字符的问题:

class HTTPResponseException(HTTPError):

    def __init__(self, response):
        self.response = response


    def __str__(self):
        return unicode(self).encode('utf-8')


    def __unicode__(self):
        msg = u'HTTP request failed with status code {}.\nURL {}\nContent {}\nHeaders {}'.format(
            self.response.status_code,
            self.response.url,
            self.response.text,
            self.response.headers)
        return msg