fix: don't re-throw TypeError from fetch() in getSession as a programming error
Node.js's undici throws TypeError: fetch failed for network failures (e.g.
AppView unreachable). The previous catch block called isProgrammingError()
which classifies all TypeErrors as code bugs and re-throws them, causing
every request to return a 500 when the AppView is down.
Fix: split the fetch() call into its own try-catch in both getSession and
getSessionWithPermissions so any throw from the raw fetch — regardless of
error type — is treated as a network failure and returns gracefully.
Adds regression tests using new TypeError("fetch failed") to match the
exact error undici produces in production.