嗅探Python urllib2.httperror内容并传递它

嗅探Python urllib2.httperror内容并传递它,python,exception,urllib2,Python,Exception,Urllib2,在一些python代码中,我使用库将请求包装到web服务。我想要的行为是,任何HTTPErrors的内容输出都带有logging.error和状态代码,并传递错误: def my_request_thing(api, other_stuff): request = make_request_from(api, other_stuff) try: with closing(urllib2.urlopen(request)) as fd: return fd.read()

在一些python代码中,我使用库将请求包装到web服务。我想要的行为是,任何HTTPErrors的内容输出都带有logging.error和状态代码,并传递错误:

def my_request_thing(api, other_stuff):
  request = make_request_from(api, other_stuff)
  try:
    with closing(urllib2.urlopen(request)) as fd:
      return fd.read()
  except HTTPError as e:
    logging.error("Error from server: %s\n%s", e.code, e.read())
    raise
这段代码将记录并传递错误,但有一个问题,异常内容在e.read中耗尽。此代码旨在用于API的大多数客户端,例如根路径和http头。。。 然后,我可能会有另一个功能,用于更特定于域的内容,使用此功能:

function get_my_thing(thing_id, conditions):
  try:
    return json.loads(my_request_thing(<thing_id + conditions into api and stuff...>))
  except HTTPError as e:
    if e.code == 404 and "my thing does not exist" in e.read():
      return False
    else:
      raise e
函数获取我的东西(东西id,条件):
尝试:
返回json.loads(my_request_thing())
除HTTPError作为e外:
如果e.code==404且e.read()中的“我的东西不存在”:
返回错误
其他:
提高e
请注意,这也会尝试使用e.read获取数据,e.read现在为空,并且可能仍然会重新验证错误。这将无法工作-此处的e.read中没有数据

有没有一种好方法可以重新引发这个异常,这样内容就不会耗尽,但我可以嗅出特定的异常类型,并在途中记录它们

根据注释,为什么不在第一次看到异常时将
e.read()
的结果作为数据成员注入异常中呢


例如,从带有空self.content的
HTTPError
派生您自己的错误类。第一次捕获异常时,从
self.read()中填充
self.content
下一个处理程序可以检查
e.content

你不能改用
e.reason
吗?除非我弄错了,否则e.reason不会保存服务器返回的内容。404告诉我没有找到什么东西。内容将显示缺少的内容。在这种情况下,为什么不在第一次看到异常时将
e.read()
的结果作为数据成员注入异常中?例如,使用空的
self.content
HTTPError
派生您自己的错误类。首次捕获异常时,从
self.read()
中填写
self.content
。Next处理程序可以检查
e.content
。这是我在一个实现中所做的-我认为派生是有意义的,因为最初我是在对HTTPError进行猴子补丁,我对此感到不舒服,因为它为它创建了一个新的非标准接口-通常是个坏主意。这里可以通过查看python请求库如何处理这一点来找到它。requests将细节填充到一个“response”对象中,该对象被返回,或者填充到它引发的异常中。它有标题、内容和状态代码。让我考虑请求而不是urllib2.这是答案,尽管Karel Kubat的评论应该得到认可。