Skip to content

Handle SuppressedError #8441

Open

Description

@timfish

Problem Statement

Explicit Resource Management has reached TC39 stage 3:
https://github.com/tc39/proposal-explicit-resource-management

Support has been added to TypeScript 5.2 beta:
https://devblogs.microsoft.com/typescript/announcing-typescript-5-2-beta/#using-declarations-and-explicit-resource-management

When this makes it into browsers/node.js/platforms, there will be a new error type called SuppressedError which wraps any exception thrown and also any exception thrown during resource disposal.

Reporting SuppressedError directly to Sentry will likely be not that useful so the error(s) should be pulled out.

class SuppressedError extends Error {
  /**
   * Wraps an error that suppresses another error, and the error that was suppressed.
   * @param {*} error The error that resulted in a suppression.
   * @param {*} suppressed The error that was suppressed.
   * @param {string} message The message for the error.
   * @param {{ cause?: * }} [options] Options for the error.
   */
  constructor(error, suppressed, message, options);

  /**
   * The name of the error (i.e., `"SuppressedError"`).
   * @type {string}
   */
  name = "SuppressedError";

  /**
   * The error that resulted in a suppression.
   * @type {*}
   */
  error;

  /**
   * The error that was suppressed.
   * @type {*}
   */
  suppressed;

  /**
   * The message for the error.
   * @type {*}
   */
  message;
}

The TypeScript introduction gives a good example of how these properties are populated:

class ErrorA extends Error {
    name = "ErrorA";
}
class ErrorB extends Error {
    name = "ErrorB";
}

function throwy(id: string) {
    return {
        [Symbol.dispose]() {
            throw new ErrorA(`Error from ${id}`);
        }
    };
}

function func() {
    using a = throwy("a");
    throw new ErrorB("oops!")
}

try {
    func();
}
catch (e: any) {
    console.log(e.name); // SuppressedError
    console.log(e.message); // An error was suppressed during disposal.

    console.log(e.error.name); // ErrorA
    console.log(e.error.message); // Error from a

    console.log(e.suppressed.name); // ErrorB
    console.log(e.suppressed.message); // oops!
}

Activity

  1. moved this to Waiting for: Product Owner in GitHub Issues with 👀on Jul 1, 2023
  2. timfish commented on Jul 2, 2023

    @timfish
    CollaboratorAuthor
  3. changed the title [-]Add support for pulling error from `SuppressedError`[/-] [+]Handle `SuppressedError`[/+] on Jul 2, 2023
  4. kunal649 commented on Oct 11, 2026

    @kunal649

    I opened a draft for this: #25246.

    So, I tried it on the Node SDK first. A SuppressedError only shows up as the wrapper ("An error was suppressed during disposal"), and cause is empty, so LinkedErrors has nothing to follow. The two real errors are on .error and .suppressed, so the PR reads those, like it does for cause and errors[].

    It's my first PR in this repo, so please tell me if you'd do something differently. I'm not suree about the is_exception_group flag on the wrapper, i explained it in the PR.

  5. JPeer264 commented on Oct 12, 2026

    @JPeer264
    Member

    hey @kunal649 thanks for opening up the PR. We'll have a look on your PR

  6. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Oct 12, 2026
  7. self-assigned this
    on Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions