当模块没有记录所有错误时要捕获哪些错误? (plistlib)

时间:2016-09-14 10:22:18

标签: python python-2.7 error-handling try-catch plist

TL; DR:当模块没有记录所有错误时要捕获哪些错误?

方案

我正在尝试使用property lists阅读一系列plistlib。我无法控制文件。如果无法读取文件,我想跳过它。

我的问题是我应该抓到什么样的错误?

plistlib.readPlist个文件IOErrorxml.parsers.expat.ExpatError

但是我也可以通过错误输入我的输入文件来产生至少IndexErrorAttributeError。这些未在plistlib中记录。谁知道其他随机输入文件会产生什么样的附加错误?我不希望我的程序因此而失败。

所以我的问题是。我应该抓到什么?我的理解是,使用通用except捕获任何错误都不是首选,因为它会掩盖其他错误,例如KeyboardInterrupt。由于这是一个命令行应用程序,我不想忽略这些事件。

代码

import plistlib
import sys

def main():
    paths = []  # from sys.argv

    for path in paths:
        try:
            plist = plistlib.readPlist(path)
        except:  # What to catch here?
            sys.stderr.write('Couldnt read plist. Ignoring.')
            continue

        process(plist) 

Python 2.7,OS X。

1 个答案:

答案 0 :(得分:3)

如果你做得不好,那么except Exception:就会避免抓住KeyboardInterruptSystemExit

然而它会捕获StopIterationGeneratorExit。可能你可以安全地向下移动到捕获StandardError(不包括那些),因为除了迭代器之外的任何代码通常被认为是错误的让StopIteration逃脱。但谁知道,也许有一些输入会导致库在耗尽的迭代器上调用next而不能捕获它。

StandardError仍会捕获SyntaxErrorTypeError,这通常是程序员错误的指示,而不是错误的输入。但是没有一个单独的类可以同时捕获LookupErrorMemoryError(两者都适合捕获)而不是SyntaxError。所以,如果没有文档或大量测试来确定代码真正抛出的内容,那么就可以了。

请注意,MemoryError不足以知道错误是暂时的(它可以在另一天或另一台机器上运行)还是永久性的(输入文件太大以至于无法想象的机器能够处理它)。