Skip to main content

Error Management Policy

Principles

  • Every error has a dedicated page that preserves the application shell (navbar + footer).
  • All error pages live under src/app/[locale]/(app)/event/ and share the event layout.
  • No raw HTML responses are served for routing errors — all failures redirect to event pages.
  • Errors are logged server-side before redirecting; client components never need to re-log routing failures.
  • Strings on error pages are always rendered in the organization's default language, resolved server-side before the client component receives them.

Error Categories

1. Routing / URL Errors

Caught before any page renders, in middleware or server-side validation.

SituationCodeDetected inRedirects to
Locale not supported by the app (e.g. /fr when French is disabled)locale_not_supportedproxy.js (middleware)/{en}/event/language?reason=not-available&from={locale}
Organization shortname does not exist in the DBorg_not_foundurlValidateServer/{locale}/event/organization-not-found
Organization exists but is blockedorg_blockedurlValidateServer/{locale}/event/organization-blocked
Locale valid globally but not configured for this tenantlocale_not_configured[locale]/(app)/layout.jsx and urlValidateServer/{defaultLocale}/event/language?reason=not-configured&from={locale}&orgName={name}

Detection layers (in order)

  1. proxy.js (Next.js middleware) — intercepts every request before routing. Redirects unsupported locales (length-2 path segments not in supportedLocales) to the language event page.
  2. urlValidateServer (src/lib/url/urlValidateServer.js) — called by route handlers (e.g. PDF download). Validates locale, org existence, org blocked status, and locale configuration. Returns NextResponse.redirect to the appropriate event page on failure.
  3. [locale]/(app)/layout.jsx — runs for all page requests. Detects MongoDB connectivity failures, locale not configured for the tenant, and ROPA fetch failures. Redirects or renders inline incident components.

2. Event Pages (/(app)/event/)

All event pages share the layout at src/app/[locale]/(app)/event/layout.jsx, which:

  • Loads the organization resiliently (silently ignores DB failures).
  • Passes an empty ROPA placeholder ({ ous: [] }) to OrganizationProvider so MiniDrawer renders without crashing.
  • Wraps children with navbar + footer exactly like the main app layout.
RoutePage fileComponentUse case
/{locale}/event/languageevent/language/page.jsxShowEventDescriptionLanguage not available or not configured
/{locale}/event/organization-not-foundevent/organization-not-found/page.jsxShowEventDescriptionOrg shortname not in DB
/{locale}/event/organization-blockedevent/organization-blocked/page.jsxShowEventDescriptionOrg is blocked

The language page reads ?reason (not-available or not-configured) and ?orgName from search params and resolves all strings server-side in the org's default locale before rendering.

Adding a new event page

  1. Create src/app/[locale]/(app)/event/{slug}/page.jsx.
  2. The event layout is inherited automatically — no layout file needed in the new directory.
  3. Add i18n keys to the appropriate namespace (urlError for org-level errors, Languages for locale errors).
  4. Wire the redirect from the detection layer (middleware or urlValidateServer).

3. Infrastructure Errors

Caught inside [locale]/(app)/layout.jsx, before the main page renders.

SituationComponentBehaviour
MongoDB unreachable or timeout (5 s)NoMongoDBRenders full-screen card without navbar (org data unavailable). Shown before any tenant context is established.
ROPA document corrupted or missing after org loadedResetCorruptedRenders inline; prompts admin to reset the ROPA.

These are not redirected to event pages because the org context required to render the event layout may itself be unavailable.


4. Unhandled / Unexpected Errors

MechanismFileBehaviour
Next.js error boundarysrc/app/error.jsxCatches unhandled runtime errors in the app segment. Renders ErrorComponent with a "Try again" button. Logs to server via logger.
Next.js 404 boundarysrc/app/not-found.jsxCatches notFound() calls. Renders NotFoundComponent.

i18n Namespaces for Error Messages

NamespaceUsed by
LanguagesLanguage event page (reason=not-available, reason=not-configured), language name labels
urlErrorOrganization-not-found and organization-blocked event pages

All strings on event pages are resolved server-side using getTranslations({ locale: defaultLocale }) so the message is always in the organization's configured default language, regardless of the locale in the URL.


Key Files

FileRole
src/proxy.jsMiddleware: intercepts unsupported locales
src/lib/url/urlValidateServer.jsRoute-handler URL validation, returns redirect responses
src/app/[locale]/(app)/layout.jsxPage-level: MongoDB, ROPA, and locale-configuration checks
src/app/[locale]/(app)/event/layout.jsxShared layout for all event pages
src/app/[locale]/(app)/event/language/page.jsxLanguage error page
src/app/[locale]/(app)/event/organization-not-found/page.jsxOrg not found page
src/app/[locale]/(app)/event/organization-blocked/page.jsxOrg blocked page
src/lib/ui/incidents/ShowEventDescription.jsxShared client component for all event page bodies
src/lib/ui/incidents/NoMongoDB.jsxMongoDB connectivity error (no navbar)
src/lib/ui/incidents/ErrorComponent.jsxUnhandled runtime error boundary component