mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-03 16:16:59 +00:00
Config, policy, branding, OAuth setup, password and setup wizard writes used to answer 500 when the shared store couldn't be reached, and the wizard's token check failed outside any handler. They answer 503 with Retry-After now, through the helper that already turned a read-only refusal into 409. The step-session-secret test's wizard mock gains wizardSessionRefusal, which the setup routes now call.
35 lines
1.5 KiB
TypeScript
35 lines
1.5 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import { isStoreUnavailableError } from '@/lib/shared-store';
|
|
|
|
/**
|
|
* The answer an admin or setup route gives when a config write failed for
|
|
* a reason the admin should see, or null for any other error, which the
|
|
* route keeps reporting as a 500:
|
|
*
|
|
* - 409 when the write hit ADMIN_CONFIG_READONLY, carrying the
|
|
* ConfigReadOnlyError message so the panel can show why nothing was
|
|
* saved (#1249).
|
|
* - 503 with Retry-After when the shared store can't be reached (#1066):
|
|
* nothing was saved, and trying again in a moment may work.
|
|
*
|
|
* By the error's name, not instanceof: the config manager on globalThis
|
|
* comes from another bundle's copy of lib/admin/paths.ts (the
|
|
* instrumentation creates it), whose ConfigReadOnlyError is a different
|
|
* class, and a read-only refusal then answered 500.
|
|
*/
|
|
export function configWriteErrorResponse(error: unknown): NextResponse | null {
|
|
if (error instanceof Error && error.name === 'ConfigReadOnlyError') {
|
|
return NextResponse.json({ error: error.message }, { status: 409 });
|
|
}
|
|
if (isStoreUnavailableError(error)) {
|
|
return NextResponse.json(
|
|
{ error: 'Nothing was saved: the shared store can\'t be reached right now. Try again in a moment.' },
|
|
{ status: 503, headers: { 'Retry-After': '10' } },
|
|
);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/** The same as configWriteErrorResponse; the name the admin routes use. */
|
|
export const configReadOnlyResponse = configWriteErrorResponse;
|