Skip to content

fix: use .maybeSingle() in saved-gigs route#446

Merged
ralyodio merged 1 commit into
profullstack:masterfrom
tankgxy:fix/saved-gigs-maybe-single
Jun 14, 2026
Merged

fix: use .maybeSingle() in saved-gigs route#446
ralyodio merged 1 commit into
profullstack:masterfrom
tankgxy:fix/saved-gigs-maybe-single

Conversation

@tankgxy

@tankgxy tankgxy commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Two .single() calls would throw 500 when checking for non-existent gigs or duplicates. Changed to .maybeSingle().

@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown

Greptile Summary

Fixes two PGRST116-driven 500 errors in the saved-gigs POST handler by replacing .single() with .maybeSingle() for the gig-existence and duplicate-check queries, where "no row found" is an expected, non-error state.

  • The gig lookup at line 109 now returns null (handled as 404) instead of throwing on a missing gig.
  • The saved-gig duplicate check at line 130 now returns null (allowing the insert to proceed) instead of throwing when the gig hasn't been saved yet.
  • The INSERT's .single() at line 143 is intentionally left unchanged — a successful insert should always return exactly one row.

Confidence Score: 4/5

Safe to merge — the core fix is correct and eliminates real 500 errors; the only concern is a pre-existing gap where .maybeSingle() errors are not checked, which could cause misleading responses under DB failure but is unlikely to cause data loss given the downstream unique constraint.

Both .maybeSingle() changes are the right call for read-only existence checks and the surrounding logic already handles null correctly. The unguarded error field in both calls is a pre-existing issue — a DB error on the duplicate-check query would silently let execution reach the INSERT, but the unique constraint in saved_gigs would catch it there. The change is small, focused, and improves the API's observable behavior for the primary happy-path and not-found cases.

src/app/api/saved-gigs/route.ts — both new .maybeSingle() calls omit error handling; worth adding error destructuring and an early 500 return to make DB failures distinguishable from not found.

Important Files Changed

Filename Overview
src/app/api/saved-gigs/route.ts Replaces two .single() calls with .maybeSingle() so that "not found" is treated as a null result rather than an error; fix is correct, but neither call checks the returned error object, so real DB errors are silently mishandled as "not found"

Sequence Diagram

sequenceDiagram
    participant Client
    participant POST /api/saved-gigs
    participant Supabase

    Client->>POST /api/saved-gigs: POST { gig_id }
    POST /api/saved-gigs->>Supabase: getAuthContext()
    Supabase-->>POST /api/saved-gigs: user

    POST /api/saved-gigs->>Supabase: gigs.select().eq(gig_id).maybeSingle()
    Note over Supabase: Returns null if not found (was 500 before)
    Supabase-->>POST /api/saved-gigs: gig | null

    alt gig is null
        POST /api/saved-gigs-->>Client: 404 Gig not found
    else "gig.status !== active"
        POST /api/saved-gigs-->>Client: 400 Can only save active gigs
    else "gig.poster_id === user.id"
        POST /api/saved-gigs-->>Client: 400 Cannot save your own gig
    else gig is valid
        POST /api/saved-gigs->>Supabase: saved_gigs.select().eq(user_id, gig_id).maybeSingle()
        Note over Supabase: Returns null if not saved (was 500 before)
        Supabase-->>POST /api/saved-gigs: existing | null

        alt existing is not null
            POST /api/saved-gigs-->>Client: 409 Gig already saved
        else
            POST /api/saved-gigs->>Supabase: saved_gigs.insert().single()
            Supabase-->>POST /api/saved-gigs: savedGig
            POST /api/saved-gigs-->>Client: 201 { saved: savedGig }
        end
    end
Loading

Comments Outside Diff (1)

  1. src/app/api/saved-gigs/route.ts, line 105-113 (link)

    P2 Errors from .maybeSingle() silently dropped

    Both .maybeSingle() calls destructure only data, discarding error. When a real database error occurs (permissions, connectivity, etc.), data is null and error is non-null — but the code interprets it as "not found" and returns 404. More importantly, the second call at line 125 would silently pass existing === null, letting execution fall through to the INSERT even though the duplicate-check query itself failed. A unique constraint would likely prevent a double-save, but the caller gets a misleading 400 instead of a 500.

    Both calls should destructure error too and return early with 500 if it is non-null.

Reviews (1): Last reviewed commit: "fix: use .maybeSingle() in saved-gigs ro..." | Re-trigger Greptile

@ralyodio ralyodio merged commit 80065de into profullstack:master Jun 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants