Challenge 2: Choose Null vs Throw — Possible Solution ==================================================================== (a) User.email hidden from non-owners -> RETURN NULL (not throw) A query touching a User object typically requests MANY fields at once (name, avatarUrl, email, etc.) — most of which are perfectly fine to show. If email throws for a non-owner, the entire query execution around it is disrupted more than necessary for what is, functionally, just "this one particular field isn't visible to you" — a completely normal, expected condition for a public-ish profile view, not an exceptional failure. Returning null lets every OTHER field the query asked for (name, avatarUrl, etc.) resolve and return successfully, exactly as this chapter's own User.email example does. This matches the chapter's guidance: null fits "you're just not allowed to see this one thing" cases well, especially for a field sitting alongside many other unrelated, accessible fields in the same object. (b) updatePost called by someone who doesn't own the post -> THROW (not return null) This is fundamentally different from (a): the CALLER is attempting an ACTION (a write), not just requesting to view a piece of data that happens to be restricted. Returning null here would be actively misleading — a client calling updatePost and getting back null could easily misinterpret that as "the post doesn't exist" or "the update silently did nothing," rather than "you were not permitted to perform this write at all." Throwing a clearly-coded FORBIDDEN (or UNAUTHENTICATED, if not logged in at all) error gives the client an explicit, actionable signal — exactly the kind of outcome Chapter 7 described null propagation as NOT being well suited for, since a mutation's entire purpose is to perform (or explicitly refuse) a specific action, not to quietly return a partial, ambiguous result. WHY THIS WORKS AS A DECISION FRAMEWORK ------------------------------------------- - The distinguishing question is: "is this a read of one field among many, or is this the ENTIRE point of the operation the client is performing?" A restricted field nested among many accessible ones (a) can reasonably degrade gracefully to null without misleading anyone. A restricted ACTION (b), where the whole mutation exists specifically to perform that one write, needs an explicit, unambiguous failure signal — silently "succeeding" with a null or no-op result would actively mislead the caller about what happened. - This mirrors the chapter's broader theme: authorization decisions aren't one-size-fits-all — the right response (silent null vs thrown error) depends on what's actually being protected and what a misleading response would cost the client.