These docs cover qiankun 3.0 (RC) — install it with npm i qiankun@rc. For 2.x, see the v2 docs.
Skip to content

addErrorHandler / removeErrorHandler ​

Register a global single-spa error observer, primarily for load and lifecycle failures from route-driven applications registered with registerMicroApps, then remove it with the same function reference. qiankun re-exports both functions from single-spa without changing their behavior.

Use this API for centralized logging and monitoring of route-driven applications. Initial loading, bootstrap, and first-mount failures from loadMicroApp reject handle promises. A later mount() execution failure also reaches the global observer; always handle the Promise returned by each operation. Handle those failures, and visible recovery, near the loadMicroApp instance or <MicroApp> component that owns the affected UI.

Signatures ​

ts
type AppError = Error & {
  appOrParcelName: string;
};

function addErrorHandler(handler: (error: AppError) => void): void;
function removeErrorHandler(handler: (error: AppError) => void): boolean;

appOrParcelName identifies the application or instance associated with the failure. removeErrorHandler compares function references, so an equivalent new function does not unregister the original one. It returns true when a handler was removed and false when none matched.

Usage ​

Register the observer once near host startup:

ts
import { addErrorHandler, removeErrorHandler } from 'qiankun';

type AppError = Error & { appOrParcelName: string };

const reportMicroAppError = (error: AppError) => {
  reportToMonitoring(error, {
    app: error.appOrParcelName,
  });
};

addErrorHandler(reportMicroAppError);

// During host teardown or test cleanup:
removeErrorHandler(reportMicroAppError);

The observer receives entry-loading and lifecycle failures from the route-driven registerMicroApps flow. loadMicroApp uses the root-parcel flow: initial loading, bootstrap, and first-mount failures bypass this observer. A later mount() execution failure reaches the observer, and qiankun also rejects that call’s returned Promise. Handle unmount() and update() failures at the call site instead of relying on global reporting.

The handler is global and renders nothing. For instance-level UI, observe the returned handle separately:

ts
import { loadMicroApp } from 'qiankun';

const microApp = loadMicroApp({ name, entry, container });

void microApp.mountPromise.catch((error: unknown) => {
  showFallback(container, error);
});

Keep the MicroApp handle and call unmount() when a successfully mounted view is removed.

Handle loading timeouts ​

When loadTimeout is enabled, a loading timeout produces a LoadAppTimeoutError. This class is exported from qiankun, extends QiankunError, and exposes these fields:

FieldTypeDescription
appNamestringName of the micro-app whose load timed out.
loadTimeoutnumberConfigured limit in milliseconds.
elapsednumberActual time in milliseconds between starting the timer and triggering the timeout.

For manual loads, catch the handle Promise's rejection. Route applications can use the same type check inside a global error handler:

ts
import { LoadAppTimeoutError, loadMicroApp } from 'qiankun';

const app = loadMicroApp({ name, entry, container }, { loadTimeout: 10_000 });

try {
  await app.mountPromise;
} catch (error) {
  if (error instanceof LoadAppTimeoutError) {
    reportToMonitoring(error, {
      app: error.appName,
      loadTimeout: error.loadTimeout,
      elapsed: error.elapsed,
    });
  }
  showFallback(container, error);
}

Before rejecting the timed-out load, qiankun cancels its loading work, removes partially written nodes and the sandbox, and releases the container. Retry by calling loadMicroApp again to create an instance; do not remount the failed handle. loadTimeout covers the loading phase only, not the micro-app's bootstrap, mount, or unmount lifecycle.

A LoadAppTimeoutError has the code load-timeout. An invalid timeout configuration throws a QiankunError with the code load-timeout-invalid. See load-timeout: Micro app loading timed out and load-timeout-invalid: Invalid loading timeout for troubleshooting.

Handler responsibilities ​

  • Keep handlers defensive: report the error and return instead of throwing another error.
  • Avoid starting an unlimited retry loop from the global channel.
  • Do not show raw stack traces or sensitive response data to users.
  • Use production source maps so monitoring can resolve transformed application stacks.

React and Vue <MicroApp> components provide component-level error UI through their own boundary options. They are built on loadMicroApp, so handle and report their instance failures through the component rather than relying on the global observer.

QiankunError ​

Use the top-level QiankunError export to identify framework errors thrown by qiankun. Framework errors from the loader, sandbox, and shared modules are all instances of it, and its read-only code property provides a stable error identifier.

ts
import { QiankunError } from 'qiankun';

void microApp.mountPromise.catch((error: unknown) => {
  if (error instanceof QiankunError) {
    reportToMonitoring(error, { code: error.code });
  }
  showFallback(container, error);
});

Errors from micro-app code, browser networking, and single-spa are not necessarily instances of QiankunError and still need handling. See Error codes and solutions for code conventions and troubleshooting guidance.

Released under the MIT License.