تكرار السؤال: …
الإجابة المختصرة
عندما تفشل عدة عمليات متزامنة في نفس الوقت (مثل مهام TaskGroup) وتحتاج عرض كل الأخطاء ومعالجة كل نوع منها، بدل الاكتفاء بأول خطأ.
الشرح
يجمع ExceptionGroup (منذ Python 3.11) عدة استثناءات في كائن واحد. تتيح except* معالجة الأنواع المطابقة داخل المجموعة، ويمكن أن تُنفذ أكثر من كتلة except* لنفس المجموعة، وما لم يُعالج يُعاد رفعه تلقائيًا في مجموعة جديدة. TaskGroup ترفع ExceptionGroup دائمًا عند فشل أي مهمة، لذلك يجب أن يعرف الكود المستدعي هذا الشكل. لا تستخدمها في الكود المتسلسل العادي.
مثال بالكود
import asyncio
async def main():
try:
async with asyncio.TaskGroup() as tg:
tg.create_task(fetch_users())
tg.create_task(fetch_orders())
except* TimeoutError as group:
log.warning("timeouts: %s", group.exceptions)
except* ValueError as group:
log.error("bad data: %s", group.exceptions)أخطاء شائعة
- كتابة except TimeoutError حول TaskGroup فلا يُلتقط شيء لأن المرفوع ExceptionGroup.
- الخلط بين except و except* في نفس جملة try (غير مسموح).
أسئلة متابعة
- ما الفرق العملي بين asyncio.gather و TaskGroup؟
- كيف تختار الاستثناء المناسب وتتعامل مع تسلسله الهرمي؟