Error Model

Three error types cover every failure mode in the SDK

HTTPError

Thrown when the server returns a non-2xx HTTP response. Extends Error.

class HTTPError extends Error {
  status: number;       // HTTP status code (e.g. 401, 403, 404)
  statusText: string;    // HTTP status text
  url: string;           // request URL that failed
  headers: Headers;      // response headers
  bodyText?: string;     // raw response body if available (capped at ~64KB)
}

Common statuses to handle: 401 (not authenticated — SDK retries via refresh), 403 (insufficient permissions), 404 (resource not found), 422 (validation failure).

RpcError

Thrown by sdk.rpc.execute() when the WASM contract returns a JSON-RPC error object. Extends Error.

class RpcError extends Error {
  code: number;           // JSON-RPC error code
  type?: string;          // optional error type from contract
  data?: unknown;         // optional structured error data
}

The message field (from Error) contains the human-readable error description from the contract.

AbortError

Thrown when a request is cancelled or times out. This is a browser-native DOMException with name === 'AbortError', not a custom class.

// Timeout fires after config.timeoutMs (default: 10 000 ms)
try {
  await sdk.admin.getContexts();
} catch (err) {
  if (err.name === 'AbortError') {
    // timed out or manually cancelled
  }
}

Full Handling Pattern

import { HTTPError, RpcError } from '@calimero-network/mero-js';

async function safeExecute() {
  try {
    const result = await sdk.rpc.execute({
      contextId: 'ctx-id',
      method: 'get_value',
      argsJson: { key: 'foo' },
    });
    return result;
  } catch (err) {
    if (err instanceof RpcError) {
      // Contract-level error — the WASM returned an error object
      console.error(`Contract error ${err.code}: ${err.message}`, err.data);
    } else if (err instanceof HTTPError) {
      // Transport-level error — HTTP 4xx/5xx
      if (err.status === 403) {
        console.error('Permission denied');
      } else {
        console.error(`HTTP ${err.status}: ${err.statusText}`);
      }
    } else if (err.name === 'AbortError') {
      // Timeout or manual cancellation
      console.warn('Request timed out');
    } else {
      // Network error (offline, CORS, DNS)
      throw err;
    }
  }
}

Note on 401s

The SDK handles 401 Unauthorized responses internally — it triggers a token refresh and retries the original request transparently. Your code will only see a 401 HTTPError if the refresh itself fails (e.g. the refresh token is also expired). In that case, call sdk.clearToken() and prompt the user to re-authenticate.