如何捕获异常并继续而不停止

时间:2015-06-11 23:50:39

标签: python exception

我有以下代码

import msgpack
def deserialize(data)
   return msgpack.loads(data)

for data in stream:
    print deserialize(data)

现在,问题是某些数据(可能)已损坏..我看到了这个错误:

  

UnicodeDecodeError:'utf8'编解码器无法解码位置0的字节0xcc:无效的连续字节

  1. 为什么我收到此错误?
  2. 我想抓住这个错误,不管这个错误如何继续 其余数据。
  3. 所以,我试过

    def deserialize(data)
       try:
            return msgpack.loads(data)
       except UnicodeDecodeError as e:
          logger.error(" error")
    

    但是,代码会以相同的错误停止吗?

3 个答案:

答案 0 :(得分:3)

  

为什么我收到此错误?

有几个可能的原因,但它们都归结为同样的事情:你有一些不是UTF-8的东西,但是你正试图像它一样读它。

首先,如果您实际上有原始二进制数据而不是文本,则无法将其解码为文本。 (在协议版本2.0之前,没有这样的区别,所以如果您从教程或为旧版本编写的示例代码中学习,那将会产生误导。)打包方需要将其显式打包为二进制数据。如果它使用相同的msgpack库,则使用use_bin_type=True参数。如果它正在使用其他库,则必须阅读其他库的文档。

其次,如果您有文本,但是打包器将其打包为拉丁语1,则无法将其解压缩为UTF-8。例如,该字节0xcc表示Latin-1中的Ì和相关字符集,这是一个完全有效的字符,但它是UTF-8中的错误,除非它遵循前缀字节。 (实际上,你很幸运,你得到了一个错误,而不是默默地做错误的事情并且全都喷出mojibake。)同样,如果打包方使用相同的msgpack库,那只是传递的问题双方encoding='utf8'。如果它使用不同的库,您将不得不查看该其他库的文档。 (如果你不能改变另一方,那么你需要弄清楚它正在使用什么编码 - 这可能很难,因为它可能取决于库,平台,甚至用户指定的语言环境或系统默认字符设置...)

  

我希望捕获此错误,并且无论此错误如何继续用于其余数据。

嗯,那可能你想做什么......但如果你这样做,你的现有代码应该可以正常工作。它在UnicodeDecodeError内提升except UnicodeDecodeError as e:。如果这不起作用,很可能你的实际代码看起来不像你在这里展示的那样。

值得注意的是,您似乎在源代码中混合了制表符和空格,这会导致很多问题 - 看起来它们与人类处于同一缩进级别的东西可能看起来像它们与Python编译器的缩进级别不同,反之亦然。我不太明白这会如何导致您发布的确切代码失败(除非在编译时引发IndentationError,这听起来不像您所描述的那样),但它很容易导致问题像这样甚至更复杂的代码。

答案 1 :(得分:1)

如果您只想记录' error'

def deserialize(data)
    try:
        return msgpack.loads(data)
    except:
        logger.error(" error")

如果您想记录错误的性质:

def deserialize(data)
    try:
        return msgpack.loads(data)
    except UnicodeDecodeError as e:
        # ... do something with e

如果您想避免错误,这应该解码并替换任何错误的值,see here以获得有关此错误的更优雅的解决方案/信息......

data.decode('utf-8', 'replace').encode('utf-8')

答案 2 :(得分:1)

您可以尝试unicode_errors='ignore' option

msgpack.loads(data, unicode_errors='ignore')