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

Which errors to catch when a module doesn't document all of its errors? (plistlib)

TL;DR:当一个模块没有记录它的所有错误时要捕获什么样的错误?

场景:

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

我的问题是我应该捕获什么样的错误?

plistlib.readPlist 文档 IOErrorxml.parsers.expat.ExpatError.

但我也可以通过对输入文件进行畸形处理来生成至少 IndexErrorAttributeErrorplistlib 中未记录这些内容。谁知道其他随机输入文件会产生什么样的额外错误?我不希望我的程序因此而失败。

所以我的问题是。我应该抓住什么?我的理解是,使用通用 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) 

Python2.7,OS X.

如果你不能做得更好,那么 except Exception: 避免捕获 KeyboardInterruptSystemExit

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

StandardError 仍然捕获 SyntaxErrorTypeError,它们通常是程序员错误的指标,而不是错误的输入。但是没有一个 class 可以同时捕获 LookupErrorMemoryError(两者都适合在这里捕获)而不是 SyntaxError。因此,这就是您在没有文档或大量测试以确定代码真正抛出的内容的情况下所能达到的程度。

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