We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
graia.ariadne.util.send.Safe
问题
由文档,app.send_message()的action参数可以决定当消息发送失败时该方法的行为,而graia.ariadne.util.send.Safe可以自动在发送失败后进行若干规避且重发消息。
app.send_message()
action
Ariadne/src/graia/ariadne/util/send.py
Lines 78 to 82 in 4b8f52b
问题在于app.send_message()在发送消息成功后仍有可能产生异常(虽然这种情况极其少见,例如日志记录故障之类),这种情况下app.send_message(action=Ignore)会像消息发送失败一样返回None,导致graia.ariadne.util.send.Safe多次试图重发已经发出的消息,造成简短的消息轰炸,并可能造成风控察觉。这个行为直接把Safe变成了不安全的。
app.send_message(action=Ignore)
None
Safe
如何复现
这里借用Python的一个bug python/cpython#104231 ,以及issue中举的一个例子,构造一个日志抛异常的情形。这种情形在现实应用中也可能出现,例如使用toml读取发送内容的时候。
import tomlkit # pip install tomlkit==0.11.8 from graia.ariadne.util.send import Safe from graia.ariadne.entry import Ariadne, WebsocketClientConfig from graia.ariadne.event.message import FriendMessage, MessageEvent app = Ariadne(ariadne_config( ********, '********', WebsocketClientConfig('http://********') )) @app.broadcast.receiver('FriendMessage') async def on_metacmd(app: Ariadne, event: FriendMessage) -> None: message = tomlkit.value('"hello"') await app.send_message(event, message, action = Safe) app.launch_blocking()
之后向机器人私聊任意消息,可以观察到hello被连续回复了六次。
预期行为
最直接的workaround是令graia.ariadne.util.send.Safe使用app.send_message(action=Strict),之后自行判断哪些异常是致命的,但这样在将来可能还是会出现语义问题。
app.send_message(action=Strict)
考虑到app.send_message()的作用就是发送消息,消息发送成功就应当返回成功的结果,所以更根本的解决方案是将所有消息发送成功后出现的异常降级为warning,或者至少令其不要体现在异常或返回值上。
使用环境:
日志/截图
无。
The text was updated successfully, but these errors were encountered:
b7a12d1
@EZForever 请尝试使用最新开发版进行验证
考虑到 app.send_message() 的作用就是发送消息,消息发送成功就应当返回成功的结果,所以更根本的解决方案是将所有消息发送成功后出现的异常降级为warning,或者至少令其不要体现在异常或返回值上。
很遗憾,Python 不像其他语言可以预先了解所有可能的异常/错误,所以只能暂时先如此修复
Sorry, something went wrong.
理解,这也不能算是Python语言的问题(当然Java只用Checked Exception的话当我没说),考虑到目前只有action=Safe会试图重发信息,只要这个可重试的异常列表是完备的,这个修复方案没问题。
action=Safe
不过issue这种情况的存在表示了app.send_message()的报错状态并不能完全代表消息发送成功与否,而这是反用户直觉的。在例如说有人自己使用action=Ignore然后判断返回值是否为None的情况下,可能会造成迷惑。建议更新action的文档和app.send_message()的文档添加提示,并且列出实际代表消息发送失败的异常列表。
action=Ignore
No branches or pull requests
问题
由文档,
app.send_message()
的action
参数可以决定当消息发送失败时该方法的行为,而graia.ariadne.util.send.Safe
可以自动在发送失败后进行若干规避且重发消息。Ariadne/src/graia/ariadne/util/send.py
Lines 78 to 82 in 4b8f52b
问题在于
app.send_message()
在发送消息成功后仍有可能产生异常(虽然这种情况极其少见,例如日志记录故障之类),这种情况下app.send_message(action=Ignore)
会像消息发送失败一样返回None
,导致graia.ariadne.util.send.Safe
多次试图重发已经发出的消息,造成简短的消息轰炸,并可能造成风控察觉。这个行为直接把Safe
变成了不安全的。如何复现
这里借用Python的一个bug python/cpython#104231 ,以及issue中举的一个例子,构造一个日志抛异常的情形。这种情形在现实应用中也可能出现,例如使用toml读取发送内容的时候。
之后向机器人私聊任意消息,可以观察到hello被连续回复了六次。
预期行为
最直接的workaround是令
graia.ariadne.util.send.Safe
使用app.send_message(action=Strict)
,之后自行判断哪些异常是致命的,但这样在将来可能还是会出现语义问题。考虑到
app.send_message()
的作用就是发送消息,消息发送成功就应当返回成功的结果,所以更根本的解决方案是将所有消息发送成功后出现的异常降级为warning,或者至少令其不要体现在异常或返回值上。使用环境:
日志/截图
无。
The text was updated successfully, but these errors were encountered: