# error-codes _(no submodules)_ ## Purpose Defines the stable `GRAPHQL.*` error-code registry for `@suaveplan/api-plugin-graphql` and the `GraphQLError` class consumers catch and discriminate on. Every failure path inside the package — Zod validation at `defineGraphQLPlugin`, role enforcement in `requireRoles`, argument validation in `validateArgs`, schema lookups, and duplicate-resolver registration — throws a `GraphQLError` carrying one of these codes. Upstream threw bare `Error(...)` strings; policy (CLAUDE.md rules + AGENTS.md §13) requires typed errors extending `SuaveplanError`. This file replaces every upstream `throw new Error("Authentication required")` etc. with `throw new GraphQLError(GRAPHQL_CODES.UNAUTHENTICATED, ...)` so consumers can branch on `error.code` instead of `error.message`. ## Features - 6 stable codes registered via `defineCodes("GRAPHQL", [...])`. - `GraphQLError extends SuaveplanError` — `instanceof GraphQLError` narrows `code`. - Optional `SuaveplanErrorOptions` (`cause`, `context`, `redact`) on every constructor call. ## Usage: Basic ```ts import { GraphQLError, GRAPHQL_CODES } from "@suaveplan/api-plugin-graphql"; try { plugin = defineGraphQLPlugin({ name: 1 as unknown as string, ...rest }); } catch (e) { if (e instanceof GraphQLError && e.code === GRAPHQL_CODES.INVALID_INPUT) { console.error("invalid options", e.cause); } } ``` ## Usage: Advanced ```ts import { GraphQLError, GRAPHQL_CODES } from "@suaveplan/api-plugin-graphql"; function safeAddResolver(c: ResolverComposer, t: string, f: string, fn: ResolverFn) { if (c.hasResolver(t, f)) { throw new GraphQLError( GRAPHQL_CODES.DUPLICATE_RESOLVER, `resolver already exists for ${t}.${f}`, { context: { typeName: t, fieldName: f } }, ); } c.addResolver(t, f, fn); } ``` ## API Reference | Symbol | Kind | Notes | |---|---|---| | `GRAPHQL_CODES` | const | `{ UNAUTHENTICATED, INSUFFICIENT_ROLE, VALIDATION_FAILED, INVALID_INPUT, TYPE_NOT_FOUND, DUPLICATE_RESOLVER }` — each value is the string `"GRAPHQL."`. | | `GraphQLErrorCode` | type | Union of the six string literal codes. | | `GraphQLError` | class | Extends `SuaveplanError`. Constructor: `(code, message, options?)`. `error.graphqlCode` mirrors `error.code`. | ## Implementation Notes `defineCodes` (from `@suaveplan/error`) returns a frozen const record whose value type is preserved through `(typeof GRAPHQL_CODES)[keyof typeof GRAPHQL_CODES]`. This means `error.code` is the literal union, not `string`. The base class constructor in `@suaveplan/error` is `protected`; we widen it to `public` so callers can construct errors directly when wrapping third-party failures (e.g. mapping a foreign cause). `graphqlCode` is a strongly-typed mirror of `.code` that survives transport boundaries even if a consumer narrows on `instanceof Error` instead of `instanceof GraphQLError`. Every code in `GRAPHQL_CODES` is thrown from at least one production code path; the `src/api-plugin-graphql.spec-conformance.test.ts` file pins this invariant.