在处理上述异常期间,发生了另一个异常

时间:2018-10-09 16:14:14

标签: python python-3.x

我下面有try-except来捕获JSON解析错误:

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json: {}'.format(e))

为什么During handling of the above exception, another exception occurred打印出来,我该如何解决?

json.decoder.JSONDecodeError: Expecting ',' delimiter: line 103 column 9 (char 1093)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
<....>
raise Exception('Invalid json: {}'.format(e))
Exception: Invalid json: Expecting ',' delimiter: line 103 column 9 (char 1093)

4 个答案:

答案 0 :(得分:4)

当前,您在另一个捕获的异常内引发ValueError异常时遇到了问题。这种解决方案的理由对我而言并没有多大意义,但是如果您进行更改

raise Exception('Invalid json: {}'.format(e))

收件人

raise Exception('Invalid json: {}'.format(e)) from None

制作结束代码。

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json: {}'.format(e)) from None

您应该获得捕获异常的预期结果。

例如

>>> foo = {}
>>> try:
...     var = foo['bar']
... except KeyError:
...     raise KeyError('No key bar in dict foo') from None
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
KeyError: 'No key bar in dict foo'

对不起,我无法为您解释为什么这种方法特别有效,但似乎可以解决问题。

更新: 似乎有PEP doc解释了如何在异常警告中抑制这些异常。

答案 1 :(得分:1)

由于您要在except语句中引发另一个异常,因此python只是在告诉您。

换句话说,通常您使用except处理一个异常并且不会使程序失败,但是在这种情况下,您在已经处理一个异常的同时又引发了另一个异常 , python告诉你什么。

如果这是您想要的行为,那么实际上没有什么可担心的。如果您想“摆脱”该消息,则可以在不引发其他异常的情况下将一些内容写到输出中,或者仅在不使用try/except语句的情况下使程序暂停。


按照Steven的建议,您可以执行以下操作:

raise Exception('Invalid json: {}'.format(e)) from e

要打印出两个例外,就像这样:

Traceback (most recent call last):
  File "tmp.py", line 5, in <module>
    raise Exception('Invalid json: {}'.format(e)) from e
Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  <...>
    json.decoder.JSONDecodeError: Expecting ',' delimiter: line 103 column 9 (char 1093)

或者您可以这样做:

raise Exception('Invalid json: {}'.format(e)) from None

禁止显示第一个,仅记录Invalid json...异常。


顺便说一句,做类似raise Exception('Invalid json: {}'.format(e))的事情并没有多大意义,在这一点上,您可以不理会原始异常,因为您不会向其中添加太多信息。

答案 2 :(得分:1)

Python提醒您在处理另一个异常时抛出了异常。如果出现意外情况,警告会提醒您,以便您了解原始异常。考虑如下情况:

class Resource:
  def close(self):
     if cannot_close:
       raise Error("Cannot close")

  def write_data(self, data):
     ...

some_function():
  try:
    res = Resource()
    res.write_data("some data")
  except Error as e:
    res.close()

让我们说write_data引发了一个异常,但随后close也意外地出现了。发生这种情况时,很高兴知道这两个异常。在大多数情况下,您想了解write_data引发的原始异常,但是了解close中的异常会帮助您知道close发生了一些奇怪的事情。

但是对于您的情况,您只是以一种新的方式重申了原始错误。这样可以提供更多上下文,例如:

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json from file {}: {}'.format(json_file, e))

这将为您提供未能解析为JSON的文件的路径,这是有用的上下文信息,不会出现在原始异常消息中。

因此,要告诉Python您实质上是在引发原始异常,但是有了更多上下文,您可以添加from e

with open(json_file) as j:
    try:
        json_config = json.load(j)
    except ValueError as e:
        raise Exception('Invalid json from file {}: {}'.format(json_file, e)) from e

这等效于Java中的“异常链接”,在Java中,您将原始异常提供给新异常的构造函数。

答案 3 :(得分:0)

我已经通过使用 data.get(key) 而不是 data[key] 解决了。