fix(admin): return 404 (not 500) when deleting an already-removed user
GoTrue returns an empty body for a missing-user delete, surfacing as an opaque JSON-parse error; pre-check existence via getUserById for a clean 404.
This commit is contained in:
@@ -100,16 +100,21 @@ export async function DELETE(
|
||||
|
||||
const admin = getSupabaseAdmin();
|
||||
|
||||
// Confirm the user exists up front. GoTrue replies with an empty body when
|
||||
// deleting a non-existent user, which supabase-js surfaces as an opaque
|
||||
// JSON-parse error (no status / "not found" text); a positive existence
|
||||
// check lets us return a clean 404 instead of a misleading 500.
|
||||
const { data: existing, error: lookupErr } =
|
||||
await admin.auth.admin.getUserById(id);
|
||||
if (lookupErr || !existing.user) {
|
||||
return jsonNoStore({ error: 'user not found' }, { status: 404 });
|
||||
}
|
||||
|
||||
// Delete the AUTH USER first. Only if that succeeds do we remove the tunnel
|
||||
// row, so a mid-failure never leaves an orphaned auth user with a dangling
|
||||
// tunnel (or half-deletes the tunnel of an already-gone user).
|
||||
const { error: delErr } = await admin.auth.admin.deleteUser(id);
|
||||
if (delErr) {
|
||||
const httpStatus = (delErr as { status?: number }).status;
|
||||
const message = (delErr.message ?? '').toLowerCase();
|
||||
if (httpStatus === 404 || message.includes('not found')) {
|
||||
return jsonNoStore({ error: 'user not found' }, { status: 404 });
|
||||
}
|
||||
console.error('admin user.delete: deleteUser failed', delErr);
|
||||
return jsonNoStore({ error: 'internal error' }, { status: 500 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user