fix: DBNMQTTool — 所有 publish 路径增加通用异常捕获

问题: _custom_publish / _proto_publish / _sim_publish 只 catch
json.JSONDecodeError, MqttClient.publish() 抛出的 ConnectionError
等异常未被捕获, 在 Qt 信号槽中导致静默崩溃(Windows 无 traceback).

修复:
- _custom_publish: +except Exception, 避免 toPlainText() 重复调用
- _proto_publish: +except Exception, 避免 toPlainText() 重复调用
- _sim_publish: +except Exception
- _custom_subscribe/_custom_unsubscribe: +except Exception, +_client 空检查
This commit is contained in:
wangfq
2026-07-07 14:15:36 +08:00
parent 5a2ef0be5d
commit 6eb93637c7
+42 -24
View File
@@ -453,6 +453,8 @@ class MainWindow(QMainWindow):
self._log(f"[模拟] → {topic}") self._log(f"[模拟] → {topic}")
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
QMessageBox.warning(self, "JSON 错误", str(e)) QMessageBox.warning(self, "JSON 错误", str(e))
except Exception as e:
QMessageBox.critical(self, "发布失败", f"{type(e).__name__}: {e}")
def _sim_send_loop(self): def _sim_send_loop(self):
sn = self._sim_sn.text() sn = self._sim_sn.text()
@@ -576,15 +578,18 @@ class MainWindow(QMainWindow):
if not topic or not self._mqtt.connected: if not topic or not self._mqtt.connected:
QMessageBox.warning(self, "提示", "请输入 Topic 并连接 Broker") QMessageBox.warning(self, "提示", "请输入 Topic 并连接 Broker")
return return
raw = self._proto_payload.toPlainText().strip()
try: try:
if self._proto_payload.toPlainText().strip(): if raw:
payload = json.loads(self._proto_payload.toPlainText()) payload = json.loads(raw)
else: else:
payload = build_request(CMD_DEV_INFO_QUERY) payload = build_request(CMD_DEV_INFO_QUERY)
self._mqtt.publish(topic, payload) self._mqtt.publish(topic, payload)
self._log(f"[协议] → {topic}") self._log(f"[协议] → {topic}")
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
QMessageBox.warning(self, "JSON 错误", str(e)) QMessageBox.warning(self, "JSON 错误", str(e))
except Exception as e:
QMessageBox.critical(self, "发布失败", f"{type(e).__name__}: {e}")
# ================================================================ # ================================================================
# 自定义 Topic 订阅/发布 # 自定义 Topic 订阅/发布
@@ -677,48 +682,61 @@ class MainWindow(QMainWindow):
topic = self._custom_pub_topic.text() topic = self._custom_pub_topic.text()
if not topic: if not topic:
return return
raw = self._custom_payload.toPlainText().strip()
try: try:
payload = json.loads(self._custom_payload.toPlainText()) if self._custom_payload.toPlainText().strip() else {} payload = json.loads(raw) if raw else {}
qos = int(self._custom_qos.currentText()) qos = int(self._custom_qos.currentText())
self._mqtt.publish(topic, payload, qos=qos) self._mqtt.publish(topic, payload, qos=qos)
self._log(f"[自定义] → {topic}") self._log(f"[自定义] → {topic}")
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
QMessageBox.warning(self, "JSON 错误", str(e)) QMessageBox.warning(self, "JSON 错误", str(e))
except Exception as e:
QMessageBox.critical(self, "发布失败", f"{type(e).__name__}: {e}")
self._log(f"[自定义] 发布失败: {e}")
def _custom_subscribe(self): def _custom_subscribe(self):
if not self._mqtt.connected: if not self._mqtt.connected or not self._mqtt._client:
QMessageBox.warning(self, "提示", "请先连接 Broker") QMessageBox.warning(self, "提示", "请先连接 Broker")
return return
topic = self._custom_sub_topic.text() topic = self._custom_sub_topic.text()
if not topic: if not topic:
return return
qos = int(self._custom_sub_qos.currentText()) try:
self._mqtt._client.subscribe(topic, qos=qos) qos = int(self._custom_sub_qos.currentText())
self._custom_subs[topic] = qos self._mqtt._client.subscribe(topic, qos=qos)
# 更新列表 self._custom_subs[topic] = qos
found = False # 更新列表
for i in range(self._custom_sub_list.topLevelItemCount()): found = False
item = self._custom_sub_list.topLevelItem(i) for i in range(self._custom_sub_list.topLevelItemCount()):
if item.text(0) == topic: item = self._custom_sub_list.topLevelItem(i)
item.setText(1, str(qos)) if item.text(0) == topic:
found = True item.setText(1, str(qos))
break found = True
if not found: break
self._custom_sub_list.addTopLevelItem(QTreeWidgetItem([topic, str(qos)])) if not found:
self._log(f"[订阅] {topic} (QoS={qos})") self._custom_sub_list.addTopLevelItem(QTreeWidgetItem([topic, str(qos)]))
self._log(f"[订阅] {topic} (QoS={qos})")
except Exception as e:
QMessageBox.critical(self, "订阅失败", f"{type(e).__name__}: {e}")
self._log(f"[订阅] 失败: {e}")
def _custom_unsubscribe(self): def _custom_unsubscribe(self):
items = self._custom_sub_list.selectedItems() items = self._custom_sub_list.selectedItems()
if not items: if not items:
return return
if not self._mqtt._client:
return
for item in items: for item in items:
topic = item.text(0) topic = item.text(0)
if topic in self._custom_subs: try:
self._mqtt._client.unsubscribe(topic) if topic in self._custom_subs:
del self._custom_subs[topic] self._mqtt._client.unsubscribe(topic)
idx = self._custom_sub_list.indexOfTopLevelItem(item) del self._custom_subs[topic]
self._custom_sub_list.takeTopLevelItem(idx) idx = self._custom_sub_list.indexOfTopLevelItem(item)
self._log(f"[取消订阅] {topic}") self._custom_sub_list.takeTopLevelItem(idx)
self._log(f"[取消订阅] {topic}")
except Exception as e:
self._log(f"[取消订阅] 失败: {e}")
# ================================================================ # ================================================================
# MQTT # MQTT