mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-09 23:55:12 +00:00
docs: add searchable API error reference (#12502)
## Summary - Add a searchable catalog of every error ID ZITADEL's gRPC/Connect APIs can return (`content/apis/errors.mdx`), wired into the sidebar next to "gRPC Status Codes" (with a cross-link added there too). There was previously no such reference — error IDs are assigned ad hoc at ~3,800 call sites across the backend. - `scripts/generate-error-reference.ts` scans `internal/**/*.go` and `backend/**/*.go` for `zerrors.Throw*()` call sites, resolves i18n messages, and clusters ~3,200 distinct IDs into ~1,160 distinct causes by (subsystem, gRPC code, message) — so identical causes are merged into one entry instead of repeated ~3,200 times. - Detects real ID collisions (same ID thrown for genuinely different reasons at different call sites) and surfaces them as warnings, rather than silently merging them. - Generates a worked example API response for every cause. - 116 of the highest-impact causes (covering the majority of call sites) carry an explanation written against the actual source rather than the raw message text; the rest carry a mechanically derived explanation — both are visibly labeled by source so the depth of research is transparent. - New `ErrorReference` component renders the catalog as a searchable, collapsible subsystem → gRPC code → cause tree. The generator is a standalone script (`pnpm generate:error-reference` in `apps/docs`), not wired into the docs build's `generate` chain, since scanning the whole Go backend on every docs build would be wasteful. The generated `data.json` and the curated overrides are committed, the same way `content/apis/benchmarks/**/output.json` is already committed despite being externally generated. ## Test plan - [x] `pnpm nx run @zitadel/docs:check-types` passes - [x] `pnpm nx run @zitadel/docs:lint` passes - [x] `pnpm nx run @zitadel/docs:check-links` passes - [x] Verified locally in `pnpm nx run @zitadel/docs:dev`: page renders, tree expands/collapses, search filters by ID/message, collision warnings render correctly (e.g. `AUTHZ-Kl3p0`) --------- Co-authored-by: Rajat Singh <[email protected]> Co-authored-by: Claude Sonnet 5 <[email protected]> Co-authored-by: Marco A. <[email protected]>
This commit is contained in:
co-authored by
Rajat Singh
Claude Sonnet 5
Marco A.
parent
8b87ca50d4
commit
e8d95f306b
@@ -0,0 +1,46 @@
|
||||
// Mirrors the table in content/apis/statuscodes.mdx. Kept here so
|
||||
// scripts/generate-error-reference.ts can derive HTTP statuses/example
|
||||
// responses without hand-duplicating the mapping.
|
||||
|
||||
export interface GrpcStatusEntry {
|
||||
code: number;
|
||||
name: string;
|
||||
httpStatus: number;
|
||||
httpText: string;
|
||||
}
|
||||
|
||||
export const GRPC_STATUS: Record<string, GrpcStatusEntry> = {
|
||||
OK: { code: 0, name: 'OK', httpStatus: 200, httpText: 'OK' },
|
||||
CANCELLED: { code: 1, name: 'CANCELLED', httpStatus: 499, httpText: 'Client Closed Request' },
|
||||
UNKNOWN: { code: 2, name: 'UNKNOWN', httpStatus: 500, httpText: 'Internal' },
|
||||
INVALID_ARGUMENT: { code: 3, name: 'INVALID_ARGUMENT', httpStatus: 400, httpText: 'Bad Request' },
|
||||
DEADLINE_EXCEEDED: { code: 4, name: 'DEADLINE_EXCEEDED', httpStatus: 504, httpText: 'Gateway Timeout' },
|
||||
NOT_FOUND: { code: 5, name: 'NOT_FOUND', httpStatus: 404, httpText: 'Not found' },
|
||||
ALREADY_EXISTS: { code: 6, name: 'ALREADY_EXISTS', httpStatus: 409, httpText: 'Conflict' },
|
||||
PERMISSION_DENIED: { code: 7, name: 'PERMISSION_DENIED', httpStatus: 403, httpText: 'Forbidden' },
|
||||
RESOURCE_EXHAUSTED: { code: 8, name: 'RESOURCE_EXHAUSTED', httpStatus: 429, httpText: 'Too Many Requests' },
|
||||
FAILED_PRECONDITION: { code: 9, name: 'FAILED_PRECONDITION', httpStatus: 400, httpText: 'Bad Request' },
|
||||
ABORTED: { code: 10, name: 'ABORTED', httpStatus: 409, httpText: 'Conflict' },
|
||||
OUT_OF_RANGE: { code: 11, name: 'OUT_OF_RANGE', httpStatus: 400, httpText: 'Bad Request' },
|
||||
UNIMPLEMENTED: { code: 12, name: 'UNIMPLEMENTED', httpStatus: 501, httpText: 'Not Implemented' },
|
||||
INTERNAL: { code: 13, name: 'INTERNAL', httpStatus: 500, httpText: 'Internal' },
|
||||
UNAVAILABLE: { code: 14, name: 'UNAVAILABLE', httpStatus: 503, httpText: 'Service Unavailable' },
|
||||
DATA_LOSS: { code: 15, name: 'DATA_LOSS', httpStatus: 500, httpText: 'Internal' },
|
||||
UNAUTHENTICATED: { code: 16, name: 'UNAUTHENTICATED', httpStatus: 401, httpText: 'Unauthorized' },
|
||||
};
|
||||
|
||||
// zerrors.Throw<Kind> function-name suffix -> gRPC status key.
|
||||
export const THROW_KIND_TO_GRPC_STATUS: Record<string, keyof typeof GRPC_STATUS> = {
|
||||
Internal: 'INTERNAL',
|
||||
InvalidArgument: 'INVALID_ARGUMENT',
|
||||
NotFound: 'NOT_FOUND',
|
||||
AlreadyExists: 'ALREADY_EXISTS',
|
||||
PermissionDenied: 'PERMISSION_DENIED',
|
||||
PreconditionFailed: 'FAILED_PRECONDITION',
|
||||
Unauthenticated: 'UNAUTHENTICATED',
|
||||
Unimplemented: 'UNIMPLEMENTED',
|
||||
ResourceExhausted: 'RESOURCE_EXHAUSTED',
|
||||
Unavailable: 'UNAVAILABLE',
|
||||
DeadlineExceeded: 'DEADLINE_EXCEEDED',
|
||||
Unknown: 'UNKNOWN',
|
||||
};
|
||||
@@ -974,6 +974,11 @@ export const apisSidebar: readonly SidebarItem[] = [
|
||||
label: "gRPC Status Codes",
|
||||
id: "apis/statuscodes",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
label: "Error Reference",
|
||||
id: "apis/errors",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
label: "Rate Limits (Cloud)",
|
||||
|
||||
Reference in New Issue
Block a user