Skip to main content

Overview

All SDK operations either:
  1. Throw a ZKsyncError whose .envelope gives you a structured, stable payload, or
  2. Return a result object from the try* variants: { ok: true, value } | { ok: false, error }.
This is consistent across both ethers and viem adapters.
Prefer the try* variants when you want to avoid exceptions and branch on success/failure.

What gets thrown

When the SDK throws, it throws an instance of ZKsyncError. Use isZKsyncError(e) to narrow and read the error envelope.

Envelope shape

'ZKsyncError'
Instance type for all SDK-thrown errors.

ZKsyncError.envelope: ErrorEnvelope

Categories (when to expect them)

Result style (try*) helpers

Every resource method has a try* sibling that never throws and returns a TryResult<T>.
This is especially handy for UI flows where you want to surface inline validation/state messages without a try/catch.

Revert details (when transactions fail)

If the provider exposes revert data, the adapters will decode common error types and ABIs so you can branch on them:
Notes:
  • The SDK always includes the 4-byte selector.
  • name/args appear when decodable against known ABIs; coverage will expand over time.
  • When a revert implies “not ready yet,” you’ll typically see a STATE error with a clarifying message.

Ethers & viem examples

Logging & observability

  • err.toJSON() returns a safe, structured object you can ship to logs/telemetry.
  • For local debugging, printing err shows a compact, human-readable view (category, operation, context, optional revert/cause).
Avoid parsing err.message for logic. Use the typed fields on err.envelope instead.