Skip to content

ELK layout can emit an unhandled rejection when aborted during export #3574

Closed

Description

@samuelgja

Problem

Aborting from an ELK export callback can leave an underlying promise rejection unhandled even when the caller handles the rejection returned by layout().

This exists on master 0ff666b5d7dab77ccf3cb599b455387f1fc894ea and is carried unchanged by the master-to-dev synchronization in #3573. It should be addressed separately from that sync.

Reproduction

import { shapes } from '@joint/core';
import { layout } from '@joint/layout-elk';

const controller = new AbortController();
await layout([
  new shapes.standard.Rectangle({ size: { width: 40, height: 30 } })
], {
  signal: controller.signal,
  exportElement() {
    controller.abort(new Error('cancelled during export'));
  }
}).catch(() => {});

A local diagnostic using the actual built public layout entry point handled its returned rejection, then observed one separate unhandledRejection carrying the same abort reason. Depending on the runtime's unhandled-rejection policy, this can terminate a Node process; browsers can emit unhandledrejection.

Cause and expected behavior

layout() checks the signal before synchronous export callbacks run. An export callback can then abort it. layoutWithDefaultElk() creates a promise, but abortable() returns from its already-aborted branch before attaching handlers to that underlying promise. The underlying callback subsequently throws the abort reason.

The caller should receive the abort rejection without an additional unhandled rejection. Follow-up regression coverage should abort inside an export callback and verify that catching layout() consumes the failure fully, alongside normal and already-aborted cancellation paths.

Source: abort helper, layout entry point.

Verified report: #3573 (comment)

Activity

  1. samuelgja commented on Oct 29, 2026

    @samuelgja
    ContributorAuthor

    Know. Issue, already tracked

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions