prefer-outcome-variants
Express nullable success and error state as tagged outcome variants.
Why
An optional error beside success or payload state admits contradictory combinations. Tagged variants expose complete success payloads and explicit failure context to callers.
Fix
Reuse an established Result[T, E] or declare Success | Error variants with a shared Literal discriminator. Require success payloads and the error value in their respective variants; retain typed partial progress when failures need it. Preserve accepted inputs and serialized contracts during migration.
Examples
from pydantic import BaseModel
class AudioResult(BaseModel): passed: bool = False error: str | None = None value: bytes | None = Nonefrom typing import Literalfrom pydantic import BaseModel
class RunSuccess(BaseModel): passed: Literal[True] = True value: bytes
class RunError(BaseModel): passed: Literal[False] = False error: str
type RunResult = RunSuccess | RunError