From 9c0abc12e3a1765415ffef4e18763482ace57c1e Mon Sep 17 00:00:00 2001 From: fullsizemalt <106900403+fullsizemalt@users.noreply.github.com> Date: Thu, 1 Jan 2026 02:34:31 -0800 Subject: [PATCH] refactor: robust manual serialization for shows to fix recursion crash --- backend/routers/shows.py | 82 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/backend/routers/shows.py b/backend/routers/shows.py index 1898888..aeb5743 100644 --- a/backend/routers/shows.py +++ b/backend/routers/shows.py @@ -34,6 +34,83 @@ def create_show( return db_show +def serialize_show(show: Show) -> ShowRead: + """ + Robustly serialize a Show object to ShowRead, manually handling relationships + to avoid infinite recursion in Pydantic v2/SQLModel. + """ + try: + # Base fields map directly + s_read = ShowRead( + id=show.id, + date=show.date, + slug=show.slug, + vertical_id=show.vertical_id, + venue_id=show.venue_id, + tour_id=show.tour_id, + notes=show.notes, + bandcamp_link=show.bandcamp_link, + nugs_link=show.nugs_link, + youtube_link=show.youtube_link, + # relisten_link is on model but not in ShowRead schema? + # Check schema again if needed, but safe to omit if not in schema + ) + + # Manually map relationships if present + if show.vertical: + try: + s_read.vertical = VerticalSimple( + id=show.vertical.id, + name=show.vertical.name, + slug=show.vertical.slug, + description=show.vertical.description, + logo_url=show.vertical.logo_url, + accent_color=show.vertical.accent_color + ) + except Exception as e: + print(f"Error serializing vertical for show {show.id}: {e}") + + if show.venue: + try: + s_read.venue = VenueRead( + id=show.venue.id, + name=show.venue.name, + slug=show.venue.slug, + city=show.venue.city, + state=show.venue.state, + country=show.venue.country, + capacity=show.venue.capacity, + notes=show.venue.notes + ) + except Exception as e: + print(f"Error serializing venue for show {show.id}: {e}") + + if show.tour: + try: + s_read.tour = TourRead( + id=show.tour.id, + name=show.tour.name, + slug=show.tour.slug, + start_date=show.tour.start_date, + end_date=show.tour.end_date, + notes=show.tour.notes + ) + except Exception as e: + print(f"Error serializing tour for show {show.id}: {e}") + + return s_read + + except Exception as e: + print(f"CRITICAL Error serializing show {show.id}: {e}") + # Return a minimal valid object or None? + # Safest to return basic info without relationships so user sees something + return ShowRead( + id=show.id, + date=show.date, + vertical_id=show.vertical_id, + slug=show.slug or "" + ) + @router.get("/", response_model=PaginatedResponse[ShowRead]) def read_shows( offset: int = 0, @@ -109,8 +186,11 @@ def read_shows( shows = session.exec(query.offset(offset).limit(limit)).all() + # Serialize robustly + serialized_shows = [serialize_show(s) for s in shows] + return PaginatedResponse( - data=shows, + data=serialized_shows, meta=PaginationMeta(total=total, limit=limit, offset=offset) )