Skip to content

v4.0.0 - Graceful handling of unrecognized MemberType/MemberStatus codes

Choose a tag to compare

@AustinW AustinW released this 11 Aug 06:49
· 2 commits to main since this release
b6fb03c

Breaking change

AthleteReservation, CoachReservation, JudgeReservation, GroupReservation, and VerificationResult previously used Enum::from() to parse MemberType/MemberStatus from the API, which throws \ValueError on any code the SDK doesn't enumerate. USAG's live vocabulary is wider than what's modeled — deprecated codes like PRO/JPRO are still returned in production, and the same person can get different MemberType codes from different endpoints. One unrecognized code failed the entire response collection, not just that row, and since \ValueError implements \Throwable, a consumer's catch (\Throwable) wrapper would misreport it as an API outage.

What changed:

  • ->memberType and ->status are now ?MemberType / ?MemberStatus — null when USAG returns a code this SDK doesn't model, instead of throwing.
  • DisciplineData::toEnum() now returns ?Discipline instead of throwing on an unrecognized code.
  • New memberTypeRaw / statusRaw string properties are added alongside every widened field, always populated with the original API value — so you can still see or log a code the SDK doesn't recognize yet.
  • canCompete() / canParticipate()-style methods treat a null status as "cannot compete" rather than throwing.

Migration: any code reading ->memberType or ->status (or calling DisciplineData::toEnum()) without a null check will need one — e.g. $athlete->status?->canParticipate() ?? false.

Fixes #4

Also investigated, not changed

The issue's side-note claiming RateLimitException is unreachable dead code doesn't hold up — UsaGymException::fromResponse() is called from ResolvesDtoOrThrows, which is used by all four Resources classes, so it is reachable via the normal request flow.