【问题标题】:Paho MQTT Python Client: No exceptions thrown, just stopsPaho MQTT Python 客户端:没有抛出异常,只是停止
【发布时间】:2019-02-24 20:49:13
【问题描述】:

我尝试在 python3 中设置一个 mqtt 客户端。这不是我第一次这样做,但是我遇到了一个相当奇怪的行为。 当尝试从回调函数之一(on_connect 或 on_message)调用包含错误的函数时,python 不会抛出异常(至少没有打印),它只是停在那里。我结合了一个简短的例子,它重现了这种行为。

有人有想法吗?

import paho.mqtt.client as mqtt

import re
import os.path

import json
from termcolor import colored

client = mqtt.Client()

def func():
    test = 1 + "1"
    print("Should never reach that")

def on_connect(client, userdata, flags, rc):
    """Establishes connection to broker
    """
    print("Connected to broker with result code " + str(rc))
    client.subscribe("test")

def on_message(client,userdata,msg):
    print("Recieved message on " + msg.topic)
    params = {}
    if msg.topic == "test":

        print("Invoke func")
        func()

if __name__ == "__main__":
    client.on_connect = on_connect
    client.on_message = on_message

    client.connect("localhost",1883,60)

    client.loop_forever()

这是向主题“test”发送消息时的输出:

Connected to broker with result code 0
Recieved message on test
Invoke func

当从 main 调用 func() 时,我得到了正确的 TypeError 抛出。所以有些东西在 paho 中捕获了这个异常。我查看了一个较旧的项目(尽管是 python2)并尝试重新创建该行为。那里的异常被正确抛出。我错过了什么?

编辑 我可以通过将 func() 调用放在 try 块中来捕获异常。但是,它不会在未被捕获时停止程序的执行。我不明白为什么

【问题讨论】:

    标签: python exception mqtt paho


    【解决方案1】:

    对于遇到此问题并想知道为什么 mqtt 回调中的所有异常都没有被抛出或至少不可见的任何人:与 python2 版本的 paho 相比,客户端已经捕获了调用用户设置回调函数。然后这个 catch 的输出被输出到 on_log 回调函数。如果用户没有执行此操作,则不会有可见的输出。所以只需添加

    def on_log(client, userdata, level, buff):
        print(buff)
    
    mqttc.on_log = on_log
    

    到你的代码,打印出异常。

    【讨论】:

      【解决方案2】:

      您可以使用try + expect 捕获错误,然后使用回溯手动打印错误消息和指向错误源的指针。与使用 on_log 函数相比,这将为您提供模式详细信息。

      import traceback
      
      def on_message(client, userdata, msg):
          try:
              do_something(msg)
          except:
              traceback.print_exc()
              quit(0)
      

      【讨论】:

        【解决方案3】:

        这是因为 on_message 函数被网络线程调用,并且它将将该调用包装在 try 块中以阻止 on_message 中的错误停止该线程。

        如果您想在错误中停止应用程序,那么您应该在 on_message 中使用您自己的 try 块并正确行事。

        【讨论】:

        • 刚刚深入研究了 paho 模块代码并看到了相同的内容。这在 paho 的 python2 和 python3 版本之间发生了变化。无论如何,感谢您的回答,您的解释很有意义。只需确保以某种方式打印 mqtt 的日志,以实际查看失败的原因
        • @ralvarez 提出一个新问题并参考这个问题,用 python 标记它以便语言专家可以帮助你。
        猜你喜欢
        • 2015-04-10
        • 1970-01-01
        • 1970-01-01
        • 2018-10-18
        • 2020-01-18
        • 1970-01-01
        • 2018-10-12
        • 2016-07-01
        • 2018-08-31
        相关资源
        最近更新 更多