Command Palette

Search for a command to run...

Hectal
Back to the lesson: Topic 7.3 — Exception Groups and except*
Python · Example 3 of 5 Python 3.11+

Report every bad row, not just the first

Errors are collected while the loop continues, then raised as one group at the end.

An ExceptionGroup bundles several unrelated errors into one exception, and except* handles the members of a group by type. They exist because concurrent code (like asyncio.TaskGroup) can fail in many places at once.

Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.

Ready for more? This phase has 7 hands-on exercises with automatic checks.

Practice questions

Write the code in the editor, run it, then open the model answer to compare.

01

Write check_prices(prices) that tests each value is a number greater than zero and raises one ExceptionGroup listing every bad value (ValueError for the wrong number, TypeError for text).

02

Catch the group from your first answer using two except* clauses and print how many of each kind there were.

03

Given eg = ExceptionGroup("x", [ValueError(1), OSError(2)]), print the class names of the members that are not ValueError, without using except*.

Explain it without notes

01

What problem does ExceptionGroup solve, and why was it added in Python 3.11?

02

How does except* differ from except? What happens to members that no handler matches?

03

Why does async with asyncio.TaskGroup() raise an ExceptionGroup even when only one task failed?

04

When would you raise your own ExceptionGroup?

Report every bad row, not just the first Python 3.11+
Sign in to run this example in your browser.

Expected output

invalid rows (3 sub-exceptions)
 - invalid literal for int() with base 10: 'x' | row 2
 - invalid literal for int() with base 10: '' | row 4
 - invalid literal for int() with base 10: '9z' | row 5