EmbedPDF

Async & errors

Two primitives run through the entire engine: AbortablePromise for every async call, and EngineError for every failure. Both are re-exported from @cloudpdf/engine.

AbortablePromise#

Every async method returns an AbortablePromise. It’s a real Promise subclass, so you await it like anything else — but it also lets you cancel the underlying work and (optionally) observe progress.

import { AbortablePromise } from '@cloudpdf/engine';
 
const pending = doc.page(pon).render.image({ viewport: { kind: 'width', width: 1600 } });
 
// Later — the user scrolled away before it finished:
pending.abort();
  • abort(reason?) rejects the promise immediately with an AbortError (wrapping reason if provided) and fires the internal AbortSignal so the in-flight fetch is cancelled. Aborting an already-settled promise is a no-op.
  • signal is the AbortSignal for the operation, if you need to chain cancellation.
  • onProgress(cb) subscribes to progress events and returns an unsubscribe function (operations that don’t emit progress simply never call it).
const unsub = pending.onProgress((p) => updateBar(p));
const image = await pending;
unsub();

Because AbortablePromise is a Promise subclass, any .then()/.catch()/await returns a plain promise — only the original object exposes .abort(). Keep a reference to it if you intend to cancel.

EngineError#

Failures reject with an EngineError carrying a stable code from EngineErrorCode. Use the code, not the message, for control flow.

import { EngineError, EngineErrorCode } from '@cloudpdf/engine';
 
try {
  const text = await doc.page(pon).text.read();
} catch (err) {
  if (EngineError.is(err, EngineErrorCode.Forbidden)) {
    showUpgradePrompt();
  } else if (EngineError.is(err, EngineErrorCode.Aborted)) {
    // user cancelled — ignore
  } else {
    throw err;
  }
}

Common codes#

HTTP responses from the server map onto these codes:

CodeTypical cause
UnauthenticatedMissing/invalid token (HTTP 401).
ForbiddenToken lacks the required scope (HTTP 403).
NotFoundDocument, page, or annotation doesn’t exist (HTTP 404).
DocPasswordRequired / DocPasswordIncorrectEncrypted document needs a (correct) password.
InvalidReferenceA stale or out-of-range AnnotationRef (e.g. an index ref with an old revision).
WeakAnnotationSessionConflictA structural annotation edit raced another client (HTTP 409).
NetworkThe fetch itself failed (offline, DNS, TLS).
AbortedThe operation was cancelled via abort().
InvalidArgMalformed input (e.g. an unsupported OpenInput.kind).
RuntimeUnavailableThe engine was already destroyed, or a browser API (object URLs) is unavailable.
WireFormatThe server returned an unexpected response shape.

Don’t pattern-match on error messages — they’re for humans and may change. Branch on err.code (or EngineError.is(err, code)), which is part of the stable contract.

Putting it together#

const pending = doc.page(pon).render.image({ viewport: { kind: 'width', width: 1200 } });
 
try {
  const image = await pending;
  const { url, revoke } = await image.objectUrl();
  show(url, revoke);
} catch (err) {
  if (EngineError.is(err, EngineErrorCode.Aborted)) return; // cancelled
  reportError(err);
}
Was this page helpful?

Your feedback goes directly to the documentation team.