Skip to content

prefer-match-exception-dispatch

Prefer guarded match/case for refined exception type dispatch.

Why

A long exception classifier that repeats isinstance checks and then refines one exception type hides the ordered set of provider outcomes. Guarded class cases make the type and refinement order explicit.

Fix

Consider repeated guarded class cases while preserving subclass order, guard evaluation, and fallthrough. Keep constant comparisons in guards; a bare name in a class-pattern field captures instead of comparing.

Examples

Before — flagged Repeated type checks hide an ordered provider error classifier
app/errors.py
from providers import APIConnectionError, APIStatusError, APITimeoutError
def category(error: BaseException) -> str:
if isinstance(error, TimeoutError | APITimeoutError):
return "timeout"
if isinstance(error, APIStatusError):
if error.status_code == 429:
return "rate_limit"
if error.status_code >= 500:
return "provider_5xx"
if isinstance(error, APIConnectionError):
return "connection"
return "unknown"
After — preferred Guarded class cases retain refinement fallthrough
app/errors.py
from providers import APIConnectionError, APIStatusError, APITimeoutError
def category(error: BaseException) -> str:
match error:
case TimeoutError() | APITimeoutError():
return "timeout"
case APIStatusError() if error.status_code == 429:
return "rate_limit"
case APIStatusError() if error.status_code >= 500:
return "provider_5xx"
case APIConnectionError():
return "connection"
case _:
return "unknown"