Add error handling for database failures in signup/login/profile

None of the database calls in these three places were wrapped in
try/catch, so any database hiccup (disk issue, lock contention, etc.)
surfaced as an unhandled 500 with a useless generic message and no
server-side log to explain why.

Found this while testing every page's redirects end to end: a broken
test setup on my end (an old server process left running against a
deleted database file) produced exactly this failure mode, which
would look identical to a real intermittent outage to an end user.

Now: signup and profile-update return a clear "try again in a
moment" message with the real error logged server-side; login logs
the real error but still shows the existing generic
"incorrect email or password" message to the client (matches
current behavior, avoids leaking account existence).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VL5YUEf2B9LG4xdVUQwcSg
This commit is contained in:
Claude committed 2026-09-28 06:05:51 +00:00
1 parent eb7103e97a
commit b5ee699a28
3 files changed
+49 -26

No files matched your search

+14 -6
View File
@@ -28,11 +28,19 @@ export async function PATCH(request: Request) {
return NextResponse.json({ error: message }, { status: 400 }); return NextResponse.json({ error: message }, { status: 400 });
} }
const user = await prisma.user.update({ try {
where: { id: session.user.id }, const user = await prisma.user.update({
data: parsed.data, where: { id: session.user.id },
select: { id: true, name: true, email: true, age: true, bio: true }, data: parsed.data,
}); select: { id: true, name: true, email: true, age: true, bio: true },
});
return NextResponse.json({ user }); return NextResponse.json({ user });
} catch (err) {
console.error("profile update failed:", err);
return NextResponse.json(
{ error: "We couldn't save your changes right now. Please try again in a moment." },
{ status: 503 },
);
}
} }
+20 -12
View File
@@ -26,17 +26,25 @@ export async function POST(request: Request) {
const { name, email, password, age } = parsed.data; const { name, email, password, age } = parsed.data;
const existing = await prisma.user.findUnique({ where: { email } }); try {
if (existing) { const existing = await prisma.user.findUnique({ where: { email } });
return NextResponse.json({ error: "An account with that email already exists" }, { status: 409 }); if (existing) {
return NextResponse.json({ error: "An account with that email already exists" }, { status: 409 });
}
const passwordHash = await bcrypt.hash(password, 12);
const user = await prisma.user.create({
data: { name, email, age, passwordHash },
select: { id: true, email: true, name: true },
});
return NextResponse.json({ user }, { status: 201 });
} catch (err) {
console.error("signup failed:", err);
return NextResponse.json(
{ error: "We couldn't create your account right now. Please try again in a moment." },
{ status: 503 },
);
} }
const passwordHash = await bcrypt.hash(password, 12);
const user = await prisma.user.create({
data: { name, email, age, passwordHash },
select: { id: true, email: true, name: true },
});
return NextResponse.json({ user }, { status: 201 });
} }
+15 -8
View File
@@ -18,17 +18,24 @@ export const authOptions: AuthOptions = {
async authorize(credentials) { async authorize(credentials) {
if (!credentials?.email || !credentials?.password) return null; if (!credentials?.email || !credentials?.password) return null;
await ensureDb(); try {
await ensureDb();
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
where: { email: credentials.email.toLowerCase() }, where: { email: credentials.email.toLowerCase() },
}); });
if (!user) return null; if (!user) return null;
const valid = await bcrypt.compare(credentials.password, user.passwordHash); const valid = await bcrypt.compare(credentials.password, user.passwordHash);
if (!valid) return null; if (!valid) return null;
return { id: user.id, email: user.email, name: user.name }; return { id: user.id, email: user.email, name: user.name };
} catch (err) {
// Logged so a database hiccup is visible server-side, even though
// the client only ever sees a generic "incorrect email or password".
console.error("login authorize() failed:", err);
return null;
}
}, },
}), }),
], ],