在imapclient-库的异常处理过程中,我遇到了问题。
我试图这样处理LoginError:
source = IMAPClient(host=args.source_server, port=args.source_port, ssl=not args.source_no_ssl)
try:
print('Login source...'.format(args.source_user), end='', flush=False)
source.login(args.source_user, args.source_pass)
print('OK')
except exceptions.LoginError as e:
print('ERROR: {}'.format(e))
exit()
如果有例外,我已经知道了:
Login source...ERROR: b'Invalid login'
我认为问题是format
正在调用Exception-object的__str__()
方法,并且不要尝试解码。
所以主要问题是谁可以转换此字符串
"b'Invalid login'"
像这样的普通字节对象?
b'Invalid login'
@lenik
如果我这样使用e.message.decode()
:
try:
print('Login source...'.format(args.source_user), end='', flush=False)
source.login(args.source_user, args.source_pass)
print('OK')
except exceptions.LoginError as e:
print('ERROR: {}'.format(e.message.decode()))
exit()
我遇到了AttributeError:
AttributeError: 'LoginError' object has no attribute 'message'
@snakecharmerb
try:
print('Login source...'.format(args.source_user), end='', flush=False)
source.login(args.source_user, args.source_pass)
print('OK')
except exceptions.LoginError as e:
print('ERROR: {}'.format(e.args[0].decode()))
exit()
AttributeError: 'str' object has no attribute 'decode'
答案 0 :(得分:1)
imapclient
的登录方法类似于this:
def login(self, username, password):
"""Login using *username* and *password*, returning the
server response.
"""
try:
rv = self._command_and_check(
'login',
to_unicode(username),
to_unicode(password),
unpack=True,
)
except exceptions.IMAPClientError as e:
raise exceptions.LoginError(str(e))
logger.info('Logged in as %s', username)
return rv
我们可以看到它在str
上调用了IMAPClientError
,因此,如果IMAPClientError
是用bytes
实例作为其参数创建的,那么我们最终会在{ {1}} * 。
有两种处理方法:
LoginError
元组访问原始字节: args
msg = e.args[0].decode()
在这两种方法中,我认为(1)在此特定情况下更好,但(2)在具有字符串字节的情况下更适用。
* 查看github上imaplib模块的历史,似乎它更改为显式解码错误消息,然后再从Python 3.5中的authenticate命令引发错误。因此,另一个解决方案可能是升级到Python 3.5 +。
答案 1 :(得分:1)
>>> s = "b'a'"
>>> eval(s)
b'a'
print('dir(e): {}'.format(dir(e)))
查看属性,或将其腌制到文件中并将其加载到ipython中进行解析。答案 2 :(得分:0)
您是否尝试过这样做:
>>> a = b'invalid'
>>> a
b'invalid'
>>> a.decode()
'invalid'
?
好,第二次服用
>>> import imaplib
>>> dir(imaplib.IMAP4.error)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', '__weakref__', 'args', 'message']
>>> imaplib.IMAP4.error.message
<attribute 'message' of 'exceptions.BaseException' objects>
似乎应该在那里有一个message
,因为根据消息来源,LoginError
似乎是imaplib.IMAP4.error
的后代:https://imapclient.readthedocs.io/en/2.1.0/_modules/imapclient/exceptions.html#LoginError
您可能希望在捕获异常的地方打印dir(e)
以查看其内容-__str__()
应该将某些内容转换为字节字符串。
然后再次进行有关IMAP4和IMAPClient库的对话,并在此处捕获异常:Catching imaplib exception (using IMAPClient package) in Python