【问题标题】:Python exception not caught未捕获 Python 异常
【发布时间】:2015-09-19 22:38:17
【问题描述】:

我目前正在 Python 中使用套接字和 JSON,其中我有以下代码:

class RCHandler(SocketServer.BaseRequestHandler):    
    def setup(self):
        pass

    def handle(self):
        raw = self.request.recv(1024)
        recv = raw.strip()

        if not recv:
            return

        # do some logging
        logging.debug("RECV: (%s)" % recv)

        try:
            data = json.loads(recv)
        except:
            logging.exception('JSON parse error: %s' % recv)
            return

        if recv == 'quit':
            return

问题是当我发送错误的 JSON 字符串时,例如'{"method": "test"',异常好像被抓到了,但是还是得到如下回溯:

DEBUG: 20/09/2015 12:33:57 - RECV: ({"method": "test")
ERROR: 20/09/2015 12:33:57 - JSON parse error: {"method": "test"
Traceback (most recent call last):
  File "./remoteControl.py", line 68, in handle
    data = json.loads(recv)
  File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 1 column 17 (char 16)

我在这里缺少什么?如果我发现异常,我不应该得到回溯,对吗?我的服务器类扩展了 ThreadingTCPServer,如果这与它有任何关系的话。

当我运行另一个 python 脚本时:

#!/usr/bin/python

import json
import socket

d = '{"method": "test"'

try:
    data = json.loads(d)
except:
    print "fail"

它只打印“失败”并且没有回溯。

【问题讨论】:

    标签: python exception logging


    【解决方案1】:

    确实捕获了异常,但您告诉logging 包含异常信息(包括回溯),在此处使用Logger.exception 方法:

    except:
        logging.exception('JSON parse error: %s' % recv)
    

    来自method documentation

    在根记录器上记录级别为ERROR 的消息。参数被解释为debug(),除了不检查任何传递的exc_info异常信息总是添加到日志消息中。该函数只能从异常处理程序中调用。

    强调我的

    另见Formatter.formatException() documentation;正是这个方法在这里进行了异常格式化:

    将指定的异常信息(sys.exc_info() 返回的标准异常元组)格式化为字符串。这个默认实现只使用traceback.print_exception()。返回结果字符串。

    traceback.print_exception() 这样做:

    打印异常信息和最多 limit 个从 tracebackfile 的堆栈跟踪条目。

    如果您不希望包含异常,请改用logging.error()

    except:
        logging.error('JSON parse error: %s' % recv)
    

    或者提供一个自定义的Formatter subclass 来格式化异常信息而不使用回溯。

    【讨论】:

    • 啊,我没想到。我花了几个小时调试一个不存在的错误:P 感谢您的回答! =)
    猜你喜欢
    • 2013-06-04
    • 2010-09-28
    • 2012-05-31
    • 1970-01-01
    相关资源
    最近更新 更多