Пишу бота на библиотеке AioGram
При запуске бота вся консоль в секунду забивается ошибками по типу:
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-274' coro=<Dispatcher._process_polling_updates() done, defined at C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherdispatcher.py:407> exception=RetryAfter('Flood control exceeded. Retry in 25 seconds.')>
Traceback (most recent call last):
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherdispatcher.py", line 415, in _process_polling_updates
for responses in itertools.chain.from_iterable(await self.process_updates(updates, fast)):
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherdispatcher.py", line 235, in process_updates
return await asyncio.gather(*tasks)
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherhandler.py", line 116, in notify
response = await handler_obj.handler(*args, **partial_data)
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherdispatcher.py", line 256, in process_update
return await self.message_handlers.notify(update.message)
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherhandler.py", line 107, in notify
data.update(await check_filters(handler_obj.filters, args))
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherfiltersfilters.py", line 72, in check_filters
f = await execute_filter(filter_, args)
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherfiltersfilters.py", line 56, in execute_filter
return await filter_.filter(*args, **filter_.kwargs)
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherfiltersfilters.py", line 161, in __call__
return await self.check(*args)
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherfiltersbuiltin.py", line 691, in check
admins = [member.user.id for chat_id in chat_ids for member in await obj.bot.get_chat_administrators(chat_id)]
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogramdispatcherfiltersbuiltin.py", line 691, in <listcomp>
admins = [member.user.id for chat_id in chat_ids for member in await obj.bot.get_chat_administrators(chat_id)]
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogrambotbot.py", line 2380, in get_chat_administrators
result = await self.request(api.Methods.GET_CHAT_ADMINISTRATORS, payload)
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogrambotbase.py", line 231, in request
return await api.make_request(await self.get_session(), self.server, self.__token, method, data, files,
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogrambotapi.py", line 140, in make_request
return check_result(method, response.content_type, response.status, await response.text())
File "C:UsersСасAppDataRoamingPythonPython310site-packagesaiogrambotapi.py", line 111, in check_result
raise exceptions.RetryAfter(parameters.retry_after)
aiogram.utils.exceptions.RetryAfter: Flood control exceeded. Retry in 25 seconds.
Бот работает только в лс, в группах он вообще не отвечает
Не могу никак разобраться, два дня назад работал нормально, а теперь такое…
Содержание
- Aiogram Message is not modified как исправить?
- Телеграм бот на aiogram выдает ошибку?
- Как исправить asyncio:Task exception was never retrieved?
- DateTimeField serialization error on Windows 10 #349
- Comments
- Context
- Expected Behavior
- Current Behavior
- Failure Information (for bugs)
- Steps to Reproduce
- Failure Logs
- Context
- Sys info
- MRE (just an echo bot):
- Steps to reproduce:
- Developing with asyncioВ¶
- Debug ModeВ¶
- Concurrency and MultithreadingВ¶
- Running Blocking CodeВ¶
- LoggingВ¶
Aiogram Message is not modified как исправить?
Пишу простого бота для телеграмма, выходит ошибка:
- Вопрос задан 24 нояб. 2022
- 207 просмотров
Средний 6 комментариев




Вы пытаетесь в цикле поменять текст сообщения на тот же самый текст.
Протокол телеграмма не позволяет этого делать, потому что это бессмысленно.
Вы можете:
1) помнить предыдущий текст и сравнивать новый с ним, чтобы вызыватьредактирование только если текст изменился.
2) Перехватывать и игнорировать MessageNotModified, если считаете, что эта ситуация будет редкой и лишний трафик на сервера телеги вас не беспокоят.
3) Вы можете чисто логически не редактировать сообение, если исходные параметры его не поменялись.
4) вы можете гарантированно менять исходные параметры сообщения, чтобы оно гарантированно изменило текст.
Выбирайте решение на своё усмотрение. А в той второй ошибке, что вы привели в комментах, вы не учитываете, что счетчик у вас глобальный на уровне модуля и достуен во всех функциях модуля, но если вы делаете его присвоение в коде функции, то в ней появляется локальная одноименная переменная, которая перекрывает глобальную, но в конкретно этом случае вызывает ошибку, поскольку при первой итерации у вас локальная переменная еще не определена, хотя фактически объявлена.
Вам нужно почитать как в питоне работают неймспейсы, как объявлять переменные в функции из глобального скоупа.

temjiu, видно что новичок. Просто перехватывайте и игнорируйте ошибку для начала.
На самом деле никакой БД не требуется, а помнить надо столько элементов, сколько сообщений с ценой у вас должно обновляться редактированием.
В вашем коде достаточно сохранить в отдельной локальной переменной отосланный перед циклом текст, а потом перед каждым редактированием сравнивать значение это йперемнной с вновь сгенерированным текстом. Если отличий нет, то редактировать не надо, если есть, то редактируем и перезаписываем новый текст в переменную.
Интереснее будет, если вам надо, чтобы при перезапуске бот не создавал новое сообщение, а редактировал одно из последних. Тогда первое значение можно вычитать из сообщение, или первое редактирование сделать в любом случае, но проигнорировав ошибку. При следующих редактированиях лучше всё же до ошибки не доводить. То есть не делать попытку редактирования. если текст не изменился. Это сэкономит вызовы к АПИ телеги и повысит производительность кода немного.
Не знаю поймёте ли что я тут написал, но попробуйте.
Источник
Телеграм бот на aiogram выдает ошибку?
Каждый раз выдает одну и ту же ошибку после того, как дело доходит до функций kartoxa и grecha
Task exception was never retrieved
future: exception=TypeError(«to_python() missing 1 required positional argument: ‘self’»)>
Traceback (most recent call last):
File «C:UsersДаняAppDataLocalProgramsPythonPython38libsite-packagesaiogramdispatcherdispatcher.py», line 388, in _process_polling_updates
for responses in itertools.chain.from_iterable(await self.process_updates(updates, fast)):
File «C:UsersДаняAppDataLocalProgramsPythonPython38libsite-packagesaiogramdispatcherdispatcher.py», line 225, in process_updates
return await asyncio.gather(*tasks)
File «C:UsersДаняAppDataLocalProgramsPythonPython38libsite-packagesaiogramdispatcherhandler.py», line 117, in notify
response = await handler_obj.handler(*args, **partial_data)
File «C:UsersДаняAppDataLocalProgramsPythonPython38libsite-packagesaiogramdispatcherdispatcher.py», line 246, in process_update
return await self.message_handlers.notify(update.message)
File «C:UsersДаняAppDataLocalProgramsPythonPython38libsite-packagesaiogramdispatcherhandler.py», line 117, in notify
response = await handler_obj.handler(*args, **partial_data)
File «C:UsersДаняbotmain.py», line 33, in kartoxa
await msg.answer(«Уважаю»,reply_markup=ReplyKeyboardRemove),
File «C:UsersДаняAppDataLocalProgramsPythonPython38libsite-packagesaiogramtypesmessage.py», line 339, in answer
return await self.bot.send_message(
File «C:UsersДаняAppDataLocalProgramsPythonPython38libsite-packagesaiogrambotbot.py», line 312, in send_message
reply_markup = prepare_arg(reply_markup)
File «C:UsersДаняAppDataLocalProgramsPythonPython38libsite-packagesaiogramutilspayload.py», line 56, in prepare_arg
return json.dumps(_normalize(value))
File «C:UsersДаняAppDataLocalProgramsPythonPython38libsite-packagesaiogramutilspayload.py», line 42, in _normalize
return obj.to_python()
TypeError: to_python() missing 1 required positional argument: ‘self’
main.py:
import asyncio
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton
from aiogram.types import ReplyKeyboardRemove
from aiogram import Bot, Dispatcher, executor, types
from config import BOT_TOKEN
loop = asyncio.get_event_loop()
bot = Bot(token=BOT_TOKEN,parse_mode=»HTML»)
dp = Dispatcher(bot,loop=loop)
menu=ReplyKeyboardMarkup(
keyboard=[
[KeyboardButton(text=»картоха»),
KeyboardButton(text=»гречка»)],
Источник
Как исправить asyncio:Task exception was never retrieved?
INFO:aiogram:Bot: Dgonni_Silverhend [@Dgonni_Silverhend_bot]
WARNING:aiogram:Updates were skipped successfully.
INFO:aiogram.dispatcher.dispatcher:Start polling.
ERROR:asyncio:Task exception was never retrieved
future: exception=MessageToDeleteNotFound(‘Message to delete not found’)>
Traceback (most recent call last):
File «G:Gameslibsite-packagesaiogramdispatcherdispatcher.py», line 415, in _process_polling_updates
for responses in itertools.chain.from_iterable(await self.process_updates(updates, fast)):
File «G:Gameslibsite-packagesaiogramdispatcherdispatcher.py», line 235, in process_updates
return await asyncio.gather(*tasks)
File «G:Gameslibsite-packagesaiogramdispatcherhandler.py», line 116, in notify
response = await handler_obj.handler(*args, **partial_data)
File «G:Gameslibsite-packagesaiogramdispatcherdispatcher.py», line 256, in process_update
return await self.message_handlers.notify(update.message)
File «G:Gameslibsite-packagesaiogramdispatcherhandler.py», line 116, in notify
response = await handler_obj.handler(*args, **partial_data)
File «C:UsersbaxarPycharmProjectspythonProject1main.py», line 23, in commands_ban
await message.bot.delete_message(chat_id=auth_data.GROUP_ID, message_id=message.reply_to_message.message_id)
File «G:Gameslibsite-packagesaiogrambotbot.py», line 2950, in delete_message
return await self.request(api.Methods.DELETE_MESSAGE, payload)
File «G:Gameslibsite-packagesaiogrambotbase.py», line 236, in request
return await api.make_request(await self.get_session(), self.server, self.__token, method, data, files,
File «G:Gameslibsite-packagesaiogrambotapi.py», line 140, in make_request
return check_result(method, response.content_type, response.status, await response.text())
File «G:Gameslibsite-packagesaiogrambotapi.py», line 115, in check_result
exceptions.BadRequest.detect(description)
File «G:Gameslibsite-packagesaiogramutilsexceptions.py», line 140, in detect
raise err(cls.text or description)
aiogram.utils.exceptions.MessageToDeleteNotFound: Message to delete not found
Вот ошибка кода
Вот сам код:import auth_data
import logging
from aiogram import Bot, Dispatcher, executor, types
import filters
from filters import IsAdminFilter
# logging level
logging.basicConfig(level=logging.INFO)
# Bot init
bot = Bot(token=auth_data.token)
dp = Dispatcher(bot)
@dp.message_handler(is_admin=True, commands=[‘ban’], commands_prefix=’!/’)
async def commands_ban(message: types.Message):
if not message.reply_to_message:
await message.reply(‘Эта команда должна быть ответом на сообщение ‘)
return
await message.bot.delete_message(chat_id=auth_data.GROUP_ID, message_id=message.reply_to_message.message_id)
await message.bot.kick_chat_member(chat_id=auth_data.GROUP_ID, user_id=message.reply_to_message.from_user.id)
await message.reply_to_message.reply(‘Этот пользовватель забанен’)
@dp.message_handler(content_types=[‘new_chat_members’])
async def chat_members(message: types.Message):
await message.delete()
@dp.message_handler()
async def filter_message(message: types.Message):
if «дебил» in message.text:
await message.delete()
Сам pycharm не пишет что есть какая либо ошибка , но при запуске скрипта уже в телеграмме ошибка происходит
Источник
DateTimeField serialization error on Windows 10 #349
Context
Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions.
- Operating System: Windows 10
- Python Version: 3.8.0
- aiogram version: 2.8
- aiohttp version: 3.6.2
- uvloop version (if installed): not installed
Expected Behavior
Current Behavior
OSError: [Errno 22] Invalid argument
Failure Information (for bugs)
When datetime is datetime.datetime(1970, 1, 1) the serialization on Windows 10 fails with OSError
Steps to Reproduce
Please provide detailed steps for reproducing the issue.
- await bot.kick_user(chat_id, user_id)
- print(await bot.get_chat_member(chat_id, user_id))
- you get it. no, you
Failure Logs
I would fix it like that:
but I’m not sure if it is normal, doesn’t seem to be ok to me xD
The text was updated successfully, but these errors were encountered:
Is it still reproducible?
Operating System: Windows 10
Python Version: 3.8.5
aiogram version: 2.11.2
aiohttp version: 3.7.3
uvloop version (if installed): not installed
Yep, what just happened with this code:
Context
I would fix it like that:
but I’m not sure if it is normal, doesn’t seem to be ok to me xD
It’s great works! But I’m not sure if it is normal, doesn’t seem to be ok to me xDD
it is only on windows?
The issue still persists on the most recent Aiogram version.
Sys info
OS: Windows 10 Pro for Workstations, build 19044.1889
python: 3.7.0
aiogram: 2.22.1
aiohttp: 3.8.0
MRE (just an echo bot):
Steps to reproduce:
- start the bot with the code above
- send a random msg to the bot (to see that it’s working)
- stop the bot from TG client
- receive a long traceback (attached below) from the dispatcher
The bot does not react to any subsequent actions, including pressing «Restart the bot» in TG client.
Only code re-run helps to fix it (the user has to restart the bot before you re-run the code, otherwise — the same error).
Источник
Developing with asyncioВ¶
Asynchronous programming is different from classic “sequential” programming.
This page lists common mistakes and traps and explains how to avoid them.
Debug ModeВ¶
By default asyncio runs in production mode. In order to ease the development asyncio has a debug mode.
There are several ways to enable asyncio debug mode:
Setting the PYTHONASYNCIODEBUG environment variable to 1 .
Passing debug=True to asyncio.run() .
In addition to enabling the debug mode, consider also:
setting the log level of the asyncio logger to logging.DEBUG , for example the following snippet of code can be run at startup of the application:
configuring the warnings module to display ResourceWarning warnings. One way of doing that is by using the -W default command line option.
When the debug mode is enabled:
asyncio checks for coroutines that were not awaited and logs them; this mitigates the “forgotten await” pitfall.
Many non-threadsafe asyncio APIs (such as loop.call_soon() and loop.call_at() methods) raise an exception if they are called from a wrong thread.
The execution time of the I/O selector is logged if it takes too long to perform an I/O operation.
Callbacks taking longer than 100 milliseconds are logged. The loop.slow_callback_duration attribute can be used to set the minimum execution duration in seconds that is considered “slow”.
Concurrency and MultithreadingВ¶
An event loop runs in a thread (typically the main thread) and executes all callbacks and Tasks in its thread. While a Task is running in the event loop, no other Tasks can run in the same thread. When a Task executes an await expression, the running Task gets suspended, and the event loop executes the next Task.
To schedule a callback from another OS thread, the loop.call_soon_threadsafe() method should be used. Example:
Almost all asyncio objects are not thread safe, which is typically not a problem unless there is code that works with them from outside of a Task or a callback. If there’s a need for such code to call a low-level asyncio API, the loop.call_soon_threadsafe() method should be used, e.g.:
To schedule a coroutine object from a different OS thread, the run_coroutine_threadsafe() function should be used. It returns a concurrent.futures.Future to access the result:
To handle signals and to execute subprocesses, the event loop must be run in the main thread.
The loop.run_in_executor() method can be used with a concurrent.futures.ThreadPoolExecutor to execute blocking code in a different OS thread without blocking the OS thread that the event loop runs in.
There is currently no way to schedule coroutines or callbacks directly from a different process (such as one started with multiprocessing ). The Event Loop Methods section lists APIs that can read from pipes and watch file descriptors without blocking the event loop. In addition, asyncio’s Subprocess APIs provide a way to start a process and communicate with it from the event loop. Lastly, the aforementioned loop.run_in_executor() method can also be used with a concurrent.futures.ProcessPoolExecutor to execute code in a different process.
Running Blocking CodeВ¶
Blocking (CPU-bound) code should not be called directly. For example, if a function performs a CPU-intensive calculation for 1 second, all concurrent asyncio Tasks and IO operations would be delayed by 1 second.
An executor can be used to run a task in a different thread or even in a different process to avoid blocking the OS thread with the event loop. See the loop.run_in_executor() method for more details.
LoggingВ¶
asyncio uses the logging module and all logging is performed via the «asyncio» logger.
The default log level is logging.INFO , which can be easily adjusted:
Network logging can block the event loop. It is recommended to use a separate thread for handling logs or use non-blocking IO. For example, see Dealing with handlers that block .
Источник
Asynchronous programming is different than classical “sequential” programming.
This page lists common traps and explains how to avoid them.
18.5.9.1. Debug mode of asyncio¶
The implementation of asyncio has been written for performance.
In order to ease the development of asynchronous code, you may wish to
enable debug mode.
To enable all debug checks for an application:
- Enable the asyncio debug mode globally by setting the environment variable
PYTHONASYNCIODEBUGto1, or by callingAbstractEventLoop.set_debug(). - Set the log level of the asyncio logger to
logging.DEBUG. For example, call
logging.basicConfig(level=logging.DEBUG)at startup. - Configure the
warningsmodule to displayResourceWarning
warnings. For example, use the-Wdefaultcommand line option of Python to
display them.
Examples debug checks:
- Log coroutines defined but never “yielded from”
call_soon()andcall_at()methods
raise an exception if they are called from the wrong thread.- Log the execution time of the selector
- Log callbacks taking more than 100 ms to be executed. The
AbstractEventLoop.slow_callback_durationattribute is the minimum
duration in seconds of “slow” callbacks. ResourceWarningwarnings are emitted when transports and event loops
are not closed explicitly.
18.5.9.2. Cancellation¶
Cancellation of tasks is not common in classic programming. In asynchronous
programming, not only is it something common, but you have to prepare your
code to handle it.
Futures and tasks can be cancelled explicitly with their Future.cancel()
method. The wait_for() function cancels the waited task when the timeout
occurs. There are many other cases where a task can be cancelled indirectly.
Don’t call set_result() or set_exception() method
of Future if the future is cancelled: it would fail with an exception.
For example, write:
if not fut.cancelled(): fut.set_result('done')
Don’t schedule directly a call to the set_result() or the
set_exception() method of a future with
AbstractEventLoop.call_soon(): the future can be cancelled before its method
is called.
If you wait for a future, you should check early if the future was cancelled to
avoid useless operations. Example:
@coroutine def slow_operation(fut): if fut.cancelled(): return # ... slow computation ... yield from fut # ...
The shield() function can also be used to ignore cancellation.
18.5.9.3. Concurrency and multithreading¶
An event loop runs in a thread and executes all callbacks and tasks in the same
thread. While a task is running in the event loop, no other task is running in
the same thread. But when the task uses yield from, the task is suspended
and the event loop executes the next task.
To schedule a callback from a different thread, the
AbstractEventLoop.call_soon_threadsafe() method should be used. Example:
loop.call_soon_threadsafe(callback, *args)
Most asyncio objects are not thread safe. You should only worry if you access
objects outside the event loop. For example, to cancel a future, don’t call
directly its Future.cancel() method, but:
loop.call_soon_threadsafe(fut.cancel)
To handle signals and to execute subprocesses, the event loop must be run in
the main thread.
To schedule a coroutine object from a different thread, the
run_coroutine_threadsafe() function should be used. It returns a
concurrent.futures.Future to access the result:
future = asyncio.run_coroutine_threadsafe(coro_func(), loop) result = future.result(timeout) # Wait for the result with a timeout
The AbstractEventLoop.run_in_executor() method can be used with a thread pool
executor to execute a callback in different thread to not block the thread of
the event loop.
18.5.9.4. Handle blocking functions correctly¶
Blocking functions should not be called directly. For example, if a function
blocks for 1 second, other tasks are delayed by 1 second which can have an
important impact on reactivity.
For networking and subprocesses, the asyncio module provides high-level
APIs like protocols.
An executor can be used to run a task in a different thread or even in a
different process, to not block the thread of the event loop. See the
AbstractEventLoop.run_in_executor() method.
See also
The Delayed calls section details how the
event loop handles time.
18.5.9.5. Logging¶
The asyncio module logs information with the logging module in
the logger 'asyncio'.
The default log level for the asyncio module is logging.INFO.
For those not wanting such verbosity from asyncio the log level can
be changed. For example, to change the level to logging.WARNING:
logging.getLogger('asyncio').setLevel(logging.WARNING)
18.5.9.6. Detect coroutine objects never scheduled¶
When a coroutine function is called and its result is not passed to
ensure_future() or to the AbstractEventLoop.create_task() method,
the execution of the coroutine object will never be scheduled which is
probably a bug. Enable the debug mode of asyncio
to log a warning to detect it.
Example with the bug:
import asyncio @asyncio.coroutine def test(): print("never scheduled") test()
Output in debug mode:
Coroutine test() at test.py:3 was never yielded from Coroutine object created at (most recent call last): File "test.py", line 7, in <module> test()
The fix is to call the ensure_future() function or the
AbstractEventLoop.create_task() method with the coroutine object.
18.5.9.7. Detect exceptions never consumed¶
Python usually calls sys.displayhook() on unhandled exceptions. If
Future.set_exception() is called, but the exception is never consumed,
sys.displayhook() is not called. Instead, a log is emitted when the future is deleted by the garbage collector, with the
traceback where the exception was raised.
Example of unhandled exception:
import asyncio @asyncio.coroutine def bug(): raise Exception("not consumed") loop = asyncio.get_event_loop() asyncio.ensure_future(bug()) loop.run_forever() loop.close()
Output:
Task exception was never retrieved future: <Task finished coro=<coro() done, defined at asyncio/coroutines.py:139> exception=Exception('not consumed',)> Traceback (most recent call last): File "asyncio/tasks.py", line 237, in _step result = next(coro) File "asyncio/coroutines.py", line 141, in coro res = func(*args, **kw) File "test.py", line 5, in bug raise Exception("not consumed") Exception: not consumed
Enable the debug mode of asyncio to get the
traceback where the task was created. Output in debug mode:
Task exception was never retrieved future: <Task finished coro=<bug() done, defined at test.py:3> exception=Exception('not consumed',) created at test.py:8> source_traceback: Object created at (most recent call last): File "test.py", line 8, in <module> asyncio.ensure_future(bug()) Traceback (most recent call last): File "asyncio/tasks.py", line 237, in _step result = next(coro) File "asyncio/coroutines.py", line 79, in __next__ return next(self.gen) File "asyncio/coroutines.py", line 141, in coro res = func(*args, **kw) File "test.py", line 5, in bug raise Exception("not consumed") Exception: not consumed
There are different options to fix this issue. The first option is to chain the
coroutine in another coroutine and use classic try/except:
@asyncio.coroutine def handle_exception(): try: yield from bug() except Exception: print("exception consumed") loop = asyncio.get_event_loop() asyncio.ensure_future(handle_exception()) loop.run_forever() loop.close()
Another option is to use the AbstractEventLoop.run_until_complete()
function:
task = asyncio.ensure_future(bug()) try: loop.run_until_complete(task) except Exception: print("exception consumed")
18.5.9.8. Chain coroutines correctly¶
When a coroutine function calls other coroutine functions and tasks, they
should be chained explicitly with yield from. Otherwise, the execution is
not guaranteed to be sequential.
Example with different bugs using asyncio.sleep() to simulate slow
operations:
import asyncio @asyncio.coroutine def create(): yield from asyncio.sleep(3.0) print("(1) create file") @asyncio.coroutine def write(): yield from asyncio.sleep(1.0) print("(2) write into file") @asyncio.coroutine def close(): print("(3) close file") @asyncio.coroutine def test(): asyncio.ensure_future(create()) asyncio.ensure_future(write()) asyncio.ensure_future(close()) yield from asyncio.sleep(2.0) loop.stop() loop = asyncio.get_event_loop() asyncio.ensure_future(test()) loop.run_forever() print("Pending tasks at exit: %s" % asyncio.Task.all_tasks(loop)) loop.close()
Expected output:
(1) create file (2) write into file (3) close file Pending tasks at exit: set()
Actual output:
(3) close file
(2) write into file
Pending tasks at exit: {<Task pending create() at test.py:7 wait_for=<Future pending cb=[Task._wakeup()]>>}
Task was destroyed but it is pending!
task: <Task pending create() done at test.py:5 wait_for=<Future pending cb=[Task._wakeup()]>>
The loop stopped before the create() finished, close() has been called
before write(), whereas coroutine functions were called in this order:
create(), write(), close().
To fix the example, tasks must be marked with yield from:
@asyncio.coroutine def test(): yield from asyncio.ensure_future(create()) yield from asyncio.ensure_future(write()) yield from asyncio.ensure_future(close()) yield from asyncio.sleep(2.0) loop.stop()
Or without asyncio.ensure_future():
@asyncio.coroutine def test(): yield from create() yield from write() yield from close() yield from asyncio.sleep(2.0) loop.stop()
18.5.9.9. Pending task destroyed¶
If a pending task is destroyed, the execution of its wrapped coroutine did not complete. It is probably a bug and so a warning is logged.
Example of log:
Task was destroyed but it is pending! task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()]>>
Enable the debug mode of asyncio to get the
traceback where the task was created. Example of log in debug mode:
Task was destroyed but it is pending!
source_traceback: Object created at (most recent call last):
File "test.py", line 15, in <module>
task = asyncio.ensure_future(coro, loop=loop)
task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()] created at test.py:7> created at test.py:15>
18.5.9.10. Close transports and event loops¶
When a transport is no more needed, call its close() method to release
resources. Event loops must also be closed explicitly.
If a transport or an event loop is not closed explicitly, a
ResourceWarning warning will be emitted in its destructor. By default,
ResourceWarning warnings are ignored. The Debug mode of asyncio section explains how to display them.
https://pastebin.com/Nn77CZQK
This is a scheduler module I made for a Discord bot using discord.py. It runs beautifully, but at the most random times I get this error and a scheduled task will be skipped and left in the JSON (where it should be deleted, if repeat is False).
Here’s an example error:
Task exception was never retrieved
future: <Task finished coro=<Scheduler.queue_manager() done, defined at C:UsersCraigDocumentsFSY-DiscordBotcogsscheduler.py:254> exception=KeyError('Unflaw (272536704672333840)',)>
Traceback (most recent call last):
File "C:Program FilesPython35libasynciotasks.py", line 239, in _step
result = coro.send(None)
File "C:UsersCraigDocumentsFSY-DiscordBotcogsscheduler.py", line 282, in queue_manager
del self.events[next_event.server][next_event.name]
KeyError: 'Unflaw (272536704672333840)'
I read about asyncio and task exceptions here: https://docs.python.org/3/library/asyncio-dev.html
However, I’m still not understanding what I can do to this code to make it stop throwing these errors (which completely halt the script from working thereafter).
Issue
Lets assume I have a simple code:
import asyncio
async def exc():
print(1 / 0)
loop = asyncio.get_event_loop()
loop.create_task(exc())
try:
loop.run_forever()
except KeyboardInterrupt:
loop.stop()
loop.close()
If I run it, I get error message immediately
Task exception was never retrieved
future: <Task finished coro=<exc() done, defined at qq.py:4> exception=ZeroDivisionError('division by zero',)>
Traceback (most recent call last):
File "qq.py", line 5, in exc
print(1 / 0)
ZeroDivisionError: division by zero
But, if I change loop.create_task(exc()) to task = loop.create_task(exc())
I’ll get the same error message after click ctrl+c
Why does task assignment change the time of output of error?
Solution
A Exception in the Task (of underlying asyncio.Future to be precise) can be retrieved with Future.exception(). If it’s not retrieved, the exception will be handled at release of the Future object with eventloop’s call_exception_handler.
So, as @dirn pointed, while the Task has reference (assigned to variable in your case) it’s not going be freed, therefore del task_future won’t be called, loop’s handler won’t be executed either.
Answered By — kwarunek