uidudevelopers
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

CodeCause
GRAPHQL_ERRORThe 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_ERRORThe request never got a useful HTTP response — DNS, TLS, timeout, connection reset, CORS preflight failure. cause holds the underlying transport error.
CONFIG_ERRORcreateClient was given neither a workspace nor an endpoint. Thrown when the client is built, not per request.
TOKEN_ERRORThe 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.

On this page