Foundations
Errors
How to handle UiduError and the underlying GraphQL/network failure modes.
Every SDK function throws UiduError on failure — no exceptions slip through untyped.
The shape
import { UiduError } from '@uidu/client';
class UiduError extends Error {
readonly code: string; // one of the codes below
readonly graphQLErrors?: ReadonlyArray<GraphQLError>;
readonly cause?: unknown;
}When to use which code
| Code | Cause |
|---|---|
GRAPHQL_ERROR | The server returned a 200 OK with errors[] in the body. Typical reasons: schema validation failed, the requested entity is restricted by permissions, or a resolver crashed. graphQLErrors is populated. |
NETWORK_ERROR | The request never got a useful HTTP response — DNS, TLS, timeout, connection reset, CORS preflight failure. cause holds the underlying transport error. |
CONFIG_ERROR | createClient was given neither a workspace nor an endpoint. Thrown when the client is built, not per request. |
TOKEN_ERROR | The client's getToken failed — in a custom app, the bridge couldn't produce a session token. cause holds the original error. |
Handling pattern
import { getPage, UiduError } from '@uidu/client';
try {
const page = await getPage(client, { projectId, slug });
return page;
} catch (err) {
if (err instanceof UiduError) {
if (err.code === 'GRAPHQL_ERROR') {
// Server-side reasoning. Log err.graphQLErrors for the details.
console.warn('Schema error:', err.graphQLErrors);
return null;
}
if (err.code === 'NETWORK_ERROR') {
// Retry, or surface a "service unavailable" page.
throw err;
}
}
throw err;
}Don't swallow
A common mistake: wrap every SDK call in try/catch (_) {} and return null. That hides server-side problems (a tags field crashing the resolver, a permission gate triggering a 500). Let NETWORK_ERROR bubble; only swallow GRAPHQL_ERROR if you know the schema can validly reject the request (e.g. a missing slug).
Inspecting the underlying GraphQL errors
catch (err) {
if (err instanceof UiduError && err.code === 'GRAPHQL_ERROR') {
for (const e of err.graphQLErrors ?? []) {
console.log(e.message);
console.log(e.path);
console.log(e.extensions); // server-side error metadata
}
}
}If a query fails with no error body (empty errors[] and the field nulled out), it's typically a Rails-side resolver crash. Drop the offending field from the selection and file a server-side bug.