mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
fix(api): read the error code before the status
A read-failure primitive decided from the status alone, so a 401 from a step-up or re-proof gate would have read as an ended session and sent the reader to sign-in. The code now decides first and the status is the fallback for codes it does not know. The two invitation routes answer an unknown name or e-mail with sharing.invite.no_account. Both have a second 404 with a different next step, and since every error now carries a code the clients match on it instead of on the status. The status defaults move into a module the client can import, and the contract text no longer says these arms carry no code.
This commit is contained in:
1 parent
0057b03699
commit
c300574a8e
20 files changed
+212
-128
No files matched your search
@@ -66,7 +66,11 @@ import { prisma } from "@/lib/db";
|
||||
import { getAuditLogRetentionDays } from "@/lib/jobs/audit-log-cleanup";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import { checkRateLimit } from "@/lib/rate-limit";
|
||||
import { GRANT_PARTY_SELECT, toGrantView } from "@/lib/sharing/grant-view";
|
||||
import {
|
||||
GRANT_PARTY_SELECT,
|
||||
INVITE_NO_ACCOUNT_CODE,
|
||||
toGrantView,
|
||||
} from "@/lib/sharing/grant-view";
|
||||
import { GrantError, inviteGrant } from "@/lib/sharing/grants";
|
||||
import { inviteGrantSchema } from "@/lib/validations/account-sharing";
|
||||
import { apiListSuccess, capRows, overfetch } from "@/lib/api/list-cap";
|
||||
@@ -221,7 +225,9 @@ export const POST = apiHandler(async (request: NextRequest) => {
|
||||
select: GRANT_PARTY_SELECT,
|
||||
});
|
||||
if (!invitee) {
|
||||
return apiError("No account with that name or e-mail", 404);
|
||||
return apiError("No account with that name or e-mail", 404, {
|
||||
errorCode: INVITE_NO_ACCOUNT_CODE,
|
||||
});
|
||||
}
|
||||
|
||||
await auth.commitElevation();
|
||||
|
||||
@@ -20,7 +20,10 @@ import {
|
||||
} from "@/lib/managed-profiles/guardian-list";
|
||||
import { ManagedProfileLifecycleError } from "@/lib/managed-profiles/lifecycle";
|
||||
import { checkRateLimit } from "@/lib/rate-limit";
|
||||
import { GRANT_PARTY_SELECT } from "@/lib/sharing/grant-view";
|
||||
import {
|
||||
GRANT_PARTY_SELECT,
|
||||
INVITE_NO_ACCOUNT_CODE,
|
||||
} from "@/lib/sharing/grant-view";
|
||||
import { GrantError, inviteManagedProfileGuardian } from "@/lib/sharing/grants";
|
||||
import { inviteManagedProfileGuardianSchema } from "@/lib/validations/managed-profiles";
|
||||
|
||||
@@ -106,16 +109,16 @@ export const POST = apiHandler(
|
||||
},
|
||||
select: GRANT_PARTY_SELECT,
|
||||
});
|
||||
// No `errorCode`, deliberately, and the same for the 429 above. Rate-limit
|
||||
// refusals carry none anywhere in this application, and the sibling
|
||||
// invitation route (`POST /api/account/grants`) answers an unknown
|
||||
// identifier with a bare 404 too. A code here would make one route in the
|
||||
// family unlike both. The published contract says so, and says that a
|
||||
// client resolves on `meta.errorCode` FIRST: this route's other 404 —
|
||||
// "you are not a Guardian of that profile" — does carry one, and branching
|
||||
// on the status would tell somebody to check a spelling when the real
|
||||
// answer is that the profile is no longer theirs to administer.
|
||||
if (!invitee) return apiError("No account with that name or e-mail", 404);
|
||||
// The same code the sibling invitation route (`POST /api/account/grants`)
|
||||
// answers an unknown identifier with. This route has a second 404 — "you
|
||||
// are not a Guardian of that profile", `managed_profile.not_found` — and
|
||||
// the two need different next steps, so each names itself and a client
|
||||
// never has to tell them apart by status.
|
||||
if (!invitee) {
|
||||
return apiError("No account with that name or e-mail", 404, {
|
||||
errorCode: INVITE_NO_ACCOUNT_CODE,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const grant = await inviteManagedProfileGuardian({
|
||||
|
||||
Reference in new issue
Block a user