Skip to content

Reference

Errors

Canton SDK error hierarchy — CantonError, ConfigurationError, AuthenticationError, ApiError, ValidationError, NetworkError, OperationError, and ErrorCode constants.

All typed failures thrown by @fairmint/canton-node-sdk derive from CantonError, which itself subclasses @hardlydifficult/rest-client’s RestClientError. That lets shared HTTP tooling pattern-match either hierarchy.

Use instanceof checks in handlers and inspect .context (serializable Record<string, unknown>) or ApiError’s HTTP fields where applicable.

import {
  CantonError,
  ConfigurationError,
  AuthenticationError,
  ApiError,
  ValidationError,
  NetworkError,
  OperationError,
  ErrorCode,
  OperationErrorCode,
} from '@fairmint/canton-node-sdk';

Hierarchy overview

ClassCode (ErrorCode or custom)Typical causes
CantonErrorCANTON_ERRORBase class; rarely thrown directly.
ConfigurationErrorCONFIGURATION_ERRORMissing CANTON_* vars, invalid NODE_ENV, unresolved API config in EnvLoader / BaseClient, missing party id when required.
AuthenticationErrorAUTHENTICATION_ERROROAuth failures surfaced by rest-client stack during token exchange (exact mapping depends on caller).
ApiErrorAPI_ERRORParticipant returned non-2xx; carries optional status, statusText, and context payload from the HTTP layer.
ValidationErrorVALIDATION_ERRORParameter validation before network I/O (for example numeric parsing in helpers such as createParty).
NetworkErrorNETWORK_ERRORTransport-level failures (DNS, socket) classified by HTTP client.
OperationErroroperation-specific (OperationErrorCode.*)Higher-level orchestration failures (waitForCondition timeout uses TRANSACTION_FAILED).

OperationErrorCode includes values such as MISSING_CONTRACT, MISSING_DOMAIN_ID, INSUFFICIENT_FUNDS, INVALID_AMOUNT, INVALID_PARAMETER, MINING_ROUND_NOT_FOUND, PARTY_CREATION_FAILED, TRANSACTION_FAILED.

Example — narrow errors from a ledger call

import {
  ApiError,
  Canton,
  ConfigurationError,
  ValidationError,
} from '@fairmint/canton-node-sdk';

const canton = new Canton({
  network: 'devnet',
  provider: '5n',
  partyId: 'OWN_PARTY_ID',
});

try {
  await canton.ledger.getActiveContracts({});
} catch (err) {
  if (err instanceof ConfigurationError) {
    console.error('Fix env', err.message);
  } else if (err instanceof ApiError) {
    console.error('HTTP', err.status, err.message);
  } else if (err instanceof ValidationError) {
    console.error('Bad params', err.message);
  }
  throw err;
}

When each error appears

  • ConfigurationError: EnvLoader.getCurrentNetwork() / getCurrentProvider() validation; missing auth URL; missing API URI/client id triplet in getConfig; missing party id when loading env-backed ApiConfig; BaseClient.getPartyId() when no party configured; getNodeEnv() invalid value.
  • AuthenticationError: Propagated when token acquisition fails (credentials wrong, IdP unreachable within auth layer classification).
  • ApiError: Ledger / validator / scan HTTP responses with error status after rest-client handling.
  • ValidationError: Input validation in SDK helpers before submitting requests.
  • NetworkError: Low-level request failures without HTTP semantics.
  • OperationError: Business-operation wrappers; waitForCondition throws OperationError with code TRANSACTION_FAILED on timeout.

Pitfalls

  • ApiError.context vs .response: ApiError exposes deprecated getter response as alias for context; prefer context for new code.
  • String-only catches: Downstream libraries may throw plain Error; keep a generic fallback branch.

See also

Source

src/core/errors.ts on GitHub.