Отправление сообщения об ошибке в telegram [PyQt5]
Я пытаюсь интегрировать отправку сообщения об ошибках в telegram внутри PyQt5. Я ввёл комбинацию ctrl+x для создания ошибки. После этого должен создаваться файл с атрибутами win и отправиться вместе с текстом Traceback. Я пробовал:
import io
import sys
import asyncio
import traceback
import keyboard as k
from telegram import Bot
from qasync import QEventLoop
from PyQt5.QtWidgets import QApplication, QWidget, QMessageBox
TELEGRAM_TOKEN = 'TOKEN'
CHAT_ID = 'ID'
class Main_widget(QWidget):
def __init__(self):
super().__init__()
self.x = 1
k.hook_key('ctrl', lambda e: self.switch(e))
k.hook_key('x', lambda e: self.check(e))
self.show()
def switch(self, e):
if 'down' in str(e):
self.temp = True
else:
self.temp = False
def check(self, e):
if self.temp and 'down' in str(e):
try:
if e.name == 'x':
aa = 5 / 0
except:
ex_type, ex_val, ex_tb = sys.exc_info()
excepthook(ex_type, ex_val, ex_tb)
async def send_report(tb, lines):
bot = Bot(token=TELEGRAM_TOKEN)
file_content = "\n".join(lines) or "Нет данных"
file_stream = io.StringIO(file_content)
file_stream.name = "attributes.txt"
try:
await bot.send_document(
chat_id=CHAT_ID,
document=file_stream,
caption=f"Сообщение об ошибке:\n{tb}"
)
except Exception as e:
print(f"Ошибка отправки в Telegram: {e}")
finally:
file_stream.close()
def excepthook(exc_type, exc_value, exc_tb):
tb = "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
lines = []
if win:
for name, value in win.__dict__.items():
if not callable(value) and not name.startswith("__"):
lines.append(f"{name}: {value}")
msg = QMessageBox()
msg.setIcon(QMessageBox.Critical)
msg.setWindowTitle("Ошибка")
msg.setText("Во время работы программы возникла ошибка.")
report = msg.addButton('Сообщить об ошибке и выйти', msg.ActionRole)
report.clicked.connect(lambda: send_report(tb, lines))
win.close()
msg.show()
sys.excepthook = excepthook
if __name__ == "__main__":
app = QApplication(sys.argv)
loop = QEventLoop(app)
asyncio.set_event_loop(loop)
win = Main_widget()
with loop:
loop.run_forever()
Когда код должен показывать сообщение об ошибке, основное окно закрывается и больше ничего не происходит, хотя программа всё ещё работает. Пожалуйста, помогите разобраться
Ответы (1 шт):
Автор решения: Flevtek
→ Ссылка
Мой итоговый вариант:
import os
import sys
import requests
import traceback
import keyboard as k
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QApplication, QWidget, QMessageBox
TOKEN = 'TOKEN'
CHAT_ID = 'ID'
class Main_widget(QWidget):
def __init__(self):
super().__init__()
self.x = 1
k.hook_key('ctrl', lambda e: self.switch(e))
k.hook_key('x', lambda e: self.check(e))
self.show()
def switch(self, e):
if 'down' in str(e):
self.temp = True
else:
self.temp = False
def check(self, e):
if self.temp and 'down' in str(e):
try:
if e.name == 'x':
aa = 5 / 0
except:
ex_type, ex_val, ex_tb = sys.exc_info()
excepthook(ex_type, ex_val, ex_tb)
class Error(QObject):
error = pyqtSignal(str, list, str)
def __init__(self):
super().__init__()
self.error.connect(self.show_message)
def show_message(self, tb, lines, ex_name):
if 'win' not in globals():
url = f"https://api.telegram.org/bot{TOKEN}/sendMessage"
requests.post(url, data={"chat_id": CHAT_ID, 'text': tb})
msg = QMessageBox()
msg.setWindowTitle("Ошибка")
msg.setText("При запуске программы возникла ошибка.")
msg.setIcon(QMessageBox.Critical)
msg.setInformativeText("Мы уже сообщили об этом разработчику.")
msg.setDetailedText(ex_name)
msg.addButton('Закрыть', msg.YesRole)
msg.exec_()
return
win.close()
msg = QMessageBox()
msg.setWindowTitle("Ошибка")
msg.setText("Во время работы программы произошла ошибка.")
msg.setIcon(QMessageBox.Critical)
msg.setInformativeText("Мы уже сообщили об этом разработчику.")
msg.setDetailedText(ex_name)
msg.addButton('Закрыть', msg.YesRole)
msg.exec_()
filename = 'report.txt'
with open(filename, 'w') as file:
file.writelines(lines)
url_file = f"https://api.telegram.org/bot{TOKEN}/sendDocument"
with open(filename, "rb") as file:
requests.post(url_file, data={"chat_id": CHAT_ID, 'caption': tb}, files={"document": file})
os.remove(filename)
def excepthook(exc_type, exc_value, exc_tb):
tb = "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
lines = []
if 'win' in globals():
for name, value in win.__dict__.items():
if not callable(value) and not name.startswith("__"):
lines.append(f"{name}: {value}")
error.error.emit(tb, lines, exc_type.__name__)
if __name__ == "__main__":
sys.excepthook = excepthook
app = QApplication(sys.argv)
error = Error()
win = Main_widget()
sys.exit(app.exec_())