Paho MQTT Python Client: без исключений, просто останавливается - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь настроить клиент mqtt в python3.Это не первый раз, когда я делаю это, однако я столкнулся с довольно странным поведением.При попытке вызвать функцию, которая содержит ошибку, из одной из функций обратного вызова (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

При вызове func ()из основного я получаю правильную ошибку TypeError.Так что-то ловит это исключение в пахо.Я посмотрел на более старый проект (хотя python2) и попытался воссоздать поведение.Там исключение выдается правильно.Что мне не хватает?

EDIT Я могу поймать исключение, поместив вызов func () в блок try.Тем не менее, он не останавливает выполнение программы, когда не перехватывается.Я не понимаю, почему

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

Для любого, кто сталкивается с этим и задается вопросом, почему все исключения внутри обратного вызова mqtt не генерируются или, по крайней мере, не видны: в отличие от версии paho на python2, клиенты уже перехватывают ВСЕ исключения, возникающие при вызовеПользователь установил функции обратного вызова.Выходные данные этого улова затем выводятся в функцию обратного вызова on_log.Если это не реализовано пользователем, не будет видимых результатов.Так что просто добавьте

def on_log(client, userdata, level, buff):

к своему коду, в котором вы можете распечатать исключение descri

0 голосов
/ 21 мая 2019

Вы можете перехватить ошибки, используя try + expect, а затем вручную распечатать сообщение об ошибке и указатель на источник ошибки, используя трассировку.Это даст вам подробную информацию о режиме, чем при использовании функции on_log.

import traceback

def on_message(client, userdata, msg):
    try:
        do_something(msg)
    except:
        traceback.print_exc()
        quit(0)
0 голосов
/ 20 сентября 2018

Это будет связано с тем, что функция on_message вызывается сетевым потоком, и он будет заключать этот вызов в блок try, чтобы предотвратить ошибки в on_message при остановке этого потока.

Если вы хотите из-за ошибки остановить приложение, вам следует использовать собственный блок try в on_message и вести себя соответствующим образом.

...