Premier League Predictor: Astro — Chapter 4, Exercise 1 ==================================================== TASK Explain why the gameweek and fixture routes both check their own rule in JavaScript (the 1-38 range, home_team_id === away_team_id) even though a database-level guarantee (a CHECK or UNIQUE constraint) already exists for each one. SOLUTION Both database constraints genuinely work — an out-of-range gameweek number, a duplicate (season_id, number) pair, or a fixture where home_team_id equals away_team_id will all be rejected by SQLite itself if they ever reach an INSERT statement. But rejecting a bad request isn't the same as responding to it well. Without the JavaScript checks, a bad request would still fail, but as a raw SqliteError bubbling straight up out of the route handler. Left uncaught, that becomes a generic, unstyled 500 response with no useful JSON body at all — the client has no way to know whether the problem was the gameweek number, the two team IDs being equal, or something else entirely. Checking the same rule explicitly in JavaScript first lets the route return a clean, specific, deliberately worded response before the database is even touched: a 400 with "Gameweek number must be between 1 and 38," or a 400 with "A team cannot play itself." The database constraint remains a genuine, unbypassable safety net underneath — catching the case even if a bug in the JavaScript check ever let a bad value slip through — but the explicit check is what actually turns a correctness guarantee into a genuinely useful error message. WHY THIS WORKS AS AN ANSWER ---------------------------- It explains the real distinction between "the database will reject this" and "the client gets told something useful about why," and names the concrete difference in outcome (a generic 500 vs. a specific, worded 400) that the explicit check produces.