"TypeError: coercing to Unicode: need string or buffer" while raising an exception

"TypeError: coercing to Unicode: need string or buffer" while raising an exception

我在生产系统上遇到了一些奇怪的异常:

TypeError: coercing to Unicode: need string or buffer, InvalidHTTPStatusCode found

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

代码:

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 字符)但这只是一个猜测。

您知道真正的原因吗?我该如何解决这个问题?

环境:

好的,您正在引发 InvalidHTTPStatusCode。这继承自 HTTPResponseException。这有一个 __ str__ 方法,它用返回的数据格式化一个非 unicode 字符串。

简而言之,

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

(将 u 添加到字符串的开头。)您无法重现它的原因可能是因为日志记录调用了此函数,而您没有。我敢打赌,如果您显式调用它,您会得到类似的异常。

与此同时,我将实施异常更改为以下代码,这似乎解决了响应中 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