Python3.5 Asyncio:如何阻止任务异常输出到标准输出?
Hey there, let's work through this issue you're hitting. That ConnectionResetError(104, 'Connection reset by peer') with the "Task exception was never retrieved" message is a classic network disconnect problem—your WiFi dropping cuts off the WebSocket connection between your bot and Discord, and the underlying websockets library isn't having its exception caught properly.
Here are the key fixes to get your program handling this gracefully:
1. Leverage discord.py's Auto-Reconnect (and Verify It's Enabled)
First off, discord.py's Client and Bot classes have built-in auto-reconnect logic that should kick in when the connection drops. Make sure you're not disabling it accidentally when initializing your bot:
from discord.ext import commands # auto_reconnect defaults to True, but explicitly setting it doesn't hurt bot = commands.Bot(command_prefix="!", auto_reconnect=True)
This will make the bot automatically attempt to re-establish the connection once your WiFi comes back up.
2. Catch Uncaught Task Exceptions Globally
The "Task exception was never retrieved" error means the exception from the WebSocket task isn't being handled anywhere. We can set up a global exception handler for the asyncio event loop to catch this specifically:
import asyncio def handle_uncaught_loop_exceptions(loop, context): exc = context.get("exception") # Only suppress the ConnectionResetError we care about; handle others normally if isinstance(exc, ConnectionResetError): print("⚠️ WiFi disconnected: WebSocket connection reset. Bot will reconnect when network is back.") else: # Fall back to the default handler for other exceptions loop.default_exception_handler(context) # Attach this handler when starting your event loop loop = asyncio.get_event_loop() loop.set_exception_handler(handle_uncaught_loop_exceptions)
This will stop that messy traceback from spamming your console and let your program keep running while waiting for reconnection.
3. Add Custom Disconnect/Reconnect Event Handlers
For better visibility into what's happening, use discord.py's built-in events to log disconnects and successful reconnects:
@bot.event async def on_disconnect(): print("🔌 Disconnected from Discord. Monitoring network for reconnection...") @bot.event async def on_ready(): print(f"✅ Reconnected successfully! Logged in as {bot.user.name}")
This gives you clear feedback in your text interface when the network drops and comes back.
4. Ensure asciimatics Doesn't Block the Asyncio Loop
Since you're using asciimatics for a text-based UI, make sure its rendering loop isn't blocking the asyncio event loop (which would prevent the bot from handling reconnections). If your asciimatics code is blocking, wrap it in an asyncio executor:
from asciimatics.screen import Screen import asyncio async def run_asciimatics(): await asyncio.get_event_loop().run_in_executor(None, Screen.wrapper, your_ui_function) # Start this alongside your bot's loop asyncio.create_task(run_asciimatics())
This keeps the asyncio loop free to handle network events and reconnection attempts.
With these changes, your program should handle WiFi drops smoothly: it'll log the disconnect, suppress the uncaught exception, and automatically reconnect once your network is back up—no crashes or messy tracebacks.
内容的提问来源于stack exchange,提问作者user67081

