Python 异常信息获取的最佳实践是什么

2017-12-07 07:05:55 +08:00
 conn4575

在 php 里面,所有异常都可以用 getMessage 获取,但是 py 里面获取异常的方式信息感觉五花八门,难道就没有统一的方式吗? 我知道的方式有:

  1. str(err),大部分情况下可以,但是有时获取到的是空的
  2. err.message, 有些异常没有该属性,可能导致新的异常
  3. err.args[0], 有些异常的第一个属性为字符串,一个个属性为异常码,另一些却相反(没错,说的就是你,socket.errer!)

捕获一个异常后要去查文档才知道如何正确输出,心好累…

题外话:今天捕获到一个异常,message 属性存的居然不是字符串而是一个列表,一万个 mmp !

3967 次点击
所在节点    Python
9 条回复
lgh
2017-12-07 07:25:19 +08:00
import traceback
traceback.format_exc()
zeq
2017-12-07 07:35:10 +08:00
logging.warning(‘ something ’, exc_info=True)
wizardmerlin
2017-12-07 08:48:21 +08:00
`traceback` 推荐.
(默认 python2)
简单写:
```python
import traceback

try:
raise TypeError("Oups!")
except Exception, err:
try:
raise TypeError("Again !?!")
except:
pass

traceback.print_exc()
```

如果要拿到详细信息:
```python
import traceback
import sys

try:
raise TypeError("Oups!")
except Exception, err:
try:
exc_info = sys.exc_info()

# do you usefull stuff here
# (potentially raising an exception)
try:
raise TypeError("Again !?!")
except:
pass
# end of useful stuff


finally:
# Display the *original* exception
traceback.print_exception(*exc_info)
del exc_info
````

输出结果类似如下:
```python
Traceback (most recent call last):
File "t.py", line 6, in <module>
raise TypeError("Oups!")
TypeError: Oups!
```


python3 的话, 输出信息会少一些。
```python
import traceback

try:
raise TypeError("Oups!")
except Exception as err:
try:
raise TypeError("Again !?!")
except:
pass

traceback.print_tb(err.__traceback__)
```

输出大致如下:
```
File "e3.py", line 4, in <module>
raise TypeError("Oups!")
```

关键是还是去看官方文档 traceback 模块:
python2.7: https://docs.python.org/2/library/traceback.html
python3.6: https://docs.python.org/3/library/traceback.html

我的经验来自: [stackoverflow 链接]( https://stackoverflow.com/questions/3702675/how-to-print-the-full-traceback-without-halting-the-program)
wizardmerlin
2017-12-07 08:51:00 +08:00
晕菜了。。。回复里,缩紧全毁了。 @conn4575 同学你还是直接看一下文档吧,里面有案例。
pabupa
2017-12-07 08:54:47 +08:00
可以试一下 vars(error),可以看到这个对象所有的属性和值。如果提示错误的话,就用 dir(error),可以看到这个对象的所有属性。

不过最好还是去看源码里看,这个 error 是怎么抛出,怎么构造的~
likuku
2017-12-07 09:01:04 +08:00
@wizardmerlin V2EX 支持嵌入 Gist 资源,若要展示源码,最好写在那上面,再贴链接过来即可。
siteshen
2017-12-07 09:32:44 +08:00
BaseException.args 是 python2.5 新增的属性,可以知道用户传递的是什么内容。

print(Exception(1, 2, 3).args)
# (1, 2, 3)

print(Exception('xyz').args)
# ('xyz',)

print(Exception().args)
# ()

初步了解了下 PHP 的 getMessage() 类似 python 中限定了参数为字符串的异常。

python 的异常里的内容可以是任何东西,写入的是啥,取出来的就是啥了。
异常 catcher 并不能做什么,只能规范异常 raiser 的行为。

如果 catcher 和 raiser 都是可控制的代码,可以自定义的异常,用这种方式规范代码。示例:

class SomethingError(Exception):
def __init__(self, code, message, blablabla):
self.code = code
self.message = message
self.blabla = blabla

然而即使如此,raiser 仍然可以不按“规范” raise Somthing('string', 666, []) 。
python 语言本身没有限制用户的行为,靠用户自觉。
ipwx
2017-12-07 09:43:08 +08:00
一般委托给 logging.exception 或者 logging.[error|warn|info|debug](..., exc_info=True)
pigletfly
2017-12-07 09:54:21 +08:00
sentry

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/412646

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX