Задать вопрос

Ошибка при работе c imaplib. При продолжительной работе перестает прозванивать почту. В чем может быть ошибка?

Вой мой код:

import asyncio
from datetime import datetime
import os
import imaplib

from aiogram import Bot, Dispatcher
from aiogram.enums import ParseMode
from aiogram.client.bot import DefaultBotProperties
from aiogram.exceptions import TelegramConflictError
from dotenv import find_dotenv, load_dotenv

from database.engine import create_db, drop_db, session_maker
from mail import process_email
from middleware.db import DataBaseSession
from receipt_router import receipt_router


load_dotenv(find_dotenv())

TOKEN = os.getenv('TOKEN')
bot = Bot(token=TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))

dp = Dispatcher()
dp.include_routers(
    receipt_router
)


async def polling_mail():
    while True:
        try:
            await process_email(bot=bot,
                                session=session_maker(),
                                exchanger='Name_1')
            await process_email(bot=bot,
                                session=session_maker(),
                                exchanger='Name_2')
        except imaplib.IMAP4.error as e:
            await bot.send_message(
                chat_id=os.getenv('ADMIN_ID'),
                text=f'Ошибка при попытке зайти в почту\n {e}')
        await asyncio.sleep(40)
        await bot.send_message(
                chat_id=os.getenv('ADMIN_ID'),
                text=f'новый цикл опроса{datetime.now()}')


async def on_startup(bot):

    need_drop = False
    if need_drop:
        await drop_db()

    await create_db()
    asyncio.create_task(polling_mail())
    print('бот запущен')


async def on_shutdown(bot):
    print('бот остановлен')


async def main():

    dp.startup.register(on_startup)
    dp.shutdown.register(on_shutdown)

    dp.update.middleware(DataBaseSession(session_pool=session_maker))

    await bot.delete_webhook(drop_pending_updates=True)

    try:
        await dp.start_polling(bot,
                               allowed_updates=dp.resolve_used_update_types())
    except TelegramConflictError:
        bot.send_message(
            text=("Ошибка: Конфликт с другим запросом getUpdates. "
                     "Включился второй инстанс."),
            chat_id=os.getenv('ADMIN_ID'))


asyncio.run(main())


Этот бот должен проверять два почтовых ящика на наличие новых сообщений, выбирать нужные и отправлять их в рабочую беседу.
При продолжительной работе в какой-то момент перестают читаться сообщения на почте, при этом ошибок не возникает, и бот продолжает выполнять команды. Хочу отловить эту ошибку, но пока логи пустые.

Бывает только такая ошибка:

Failed to fetch updates - TelegramConflictError: Telegram server says - Conflict: terminated by other getUpdates request; make sure that only one bot instance is running


Но она возникает из-за особенностей работы сервера: иногда включается второй инстанс. Вроде не должно влиять на работу imap.
В чем может быть дело, и как еще можно найти причину?
  • Вопрос задан
  • 100 просмотров
Подписаться 2 Простой Комментировать
Решения вопроса 1
@Everything_is_bad
При продолжительной работе
скорее всего это проблема про которую написано в оф доках https://docs.python.org/3/library/asyncio-task.htm...
Important Save a reference to the result of this function, to avoid a task disappearing mid-execution. The event loop only keeps weak references to tasks. A task that isn’t referenced elsewhere may get garbage collected at any time, even before it’s done. For reliable “fire-and-forget” background tasks, gather them in a collection:
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
anton_grenkov
@anton_grenkov Автор вопроса
В общем, пока не нашел причину. Добавление в список задач не помогло. Мб неправильно добавил. Вопрос остается открытым.

backgrounds_tasks = set()

TOKEN = os.getenv('TOKEN')
bot = Bot(token=TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))

async def main():

    dp.startup.register(on_startup)
    dp.shutdown.register(on_shutdown)

    polling_mail_task = asyncio.create_task(polling_mail())
    backgrounds_tasks.add(polling_mail_task)

    dp.update.middleware(DataBaseSession(session_pool=session_maker))

    await bot.delete_webhook(drop_pending_updates=True)

    try:
        await dp.start_polling(bot,
                               allowed_updates=dp.resolve_used_update_types())
    except TelegramConflictError:
        bot.send_message(
            text=("Ошибка: Конфликт с другим запросом getUpdates. "
                  "Включился второй инстанс."),
            chat_id=os.getenv('ADMIN_ID'))


asyncio.run(main())
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
22 дек. 2024, в 13:01
50000 руб./за проект
22 дек. 2024, в 10:44
15000 руб./за проект
22 дек. 2024, в 10:12
10000 руб./за проект