我下面有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)
答案 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]
解决了。