Skip to content

feat: errdefer#5

Merged
gjuchault merged 1 commit into
mainfrom
feat/errdefer
Jan 10, 2026
Merged

feat: errdefer#5
gjuchault merged 1 commit into
mainfrom
feat/errdefer

Conversation

@gjuchault
Copy link
Copy Markdown
Owner

@gjuchault gjuchault commented Jan 10, 2026

function* errdefer<Error>(
  callback: (error: Error) => void | Promise<void>
): Generator<Errdefer<Error>, void, unknown>;

This method is similar to errdefer in other languages (eg. zig). It allows to cleanup eventual leftovers when a method partially failed. Similar to a finally keyword.
It takes the error as parameter if you need it

Example:

let globalTimeout1: NodeJS.Timeout;
let globalTimeout2: NodeJS.Timeout;

// Two dependency starting a long-living process like a timeout or a database connection
const genLongLivingDependency1 = gen(async function longLivingDependency() {
  globalTimeout1 = setTimeout(() => {}, 1000);
  return "done";
});

const genLongLivingDependency2 = gen(async function longLivingDependency() {
  globalTimeout2 = setTimeout(() => {}, 1000);
  return "done";
});

const genFailingDependency = gen(async function failingDependency() {
  throw new Error("some failing dependency");
});

async function* main() {
  const dependency1 = yield* genLongLivingDependency1();
  // this will be called if `main` has a failure somewhere
  yield* errdefer(() => clearTimeout(globalTimeout1));

  const dependency2 = yield* genLongLivingDependency2();
  // this will be called if `main` has a failure somewhere, after the first errdefer
  yield* errdefer(() => clearTimeout(globalTimeout2));

  // since this is failing, it will call every errdefer callback, evaluated in reverse order
  const failingDependency = yield* genFailingDependency();

  return [dependency1, dependency2, failingDependency];
}

@gjuchault gjuchault merged commit 69f3283 into main Jan 10, 2026
7 checks passed
@gjuchault gjuchault deleted the feat/errdefer branch January 10, 2026 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant