defer-node-js
TypeScript icon, indicating that this package has built-in type declarations

0.7.0 • Public • Published

defer-node-js

Defer and recover for JavaScript and TypeScript, inspired by Golang. defer lets you schedule cleanup functions to run after a parent function exits, ensuring efficient resource management. recover helps handle errors gracefully, making them ideal for robust error handling and resource cleanup in complex workflows.

install

npm i defer-node-js

Introduction

In go, the defer keyword schedules a function call to be run when the parent exit. Weather by reaching the end of the funciton or by a panic. The recover function in go stops the panic and returns the error value inside the defered block.

Javascript doesn't have built-in language feature for defer or recover. Instead, developers often rely on try/finally to construct or explicit cleanup calls.

This library emulates Go's defer and recover for blocking and non-blocking functions.

Goals

  1. Resource management: Provide a simpler pattern for resource cleanup without scattering finally blocks trhoughout your code.
  2. Error handling: Allow centeral point to catch and " recover " from error that happened in the main function.

Architecture

  1. Defer stack (LIFO): We maintain a stack of deferred functions. When .defer(fn) is called, fn is pushed into the stack.

  2. .wrapper:

  • The wrapper method returns a new function that when invoked setups the ( deferr environment) which is managed stack within js stack.
  • it calls the original function capturing any errors.
  • It then executes all the defered functions LIFO.
  • If no defered funcations calls recover, the original error is rethrown.
  1. Recover: if a defered function calls .recover() and the parent function thrown an error, the bottom defered function will nullifies the error, the error is swallowed and returns with the recover() method.

deferer sequence diagram

Typical use-cases

  1. File handling
import fs from 'fs';
import { SyncDeferer } from 'defer';

const readFileSafely = SyncDeferer.wrapper((filePath: string) => {
  // open file
  const fd = fs.openSync(filePath, 'r');
  // always close file when the function returns or throws
  SyncDeferer.defer(() => fs.closeSync(fd));

  const content = fs.readFileSync(fd, 'utf-8');
  return content;
});

try {
  const data = readFileSafely('/path/to/file.txt');
  console.log('File data:', data);
} catch (error) {
  console.error('Failed to read file:', error);
}

  1. Networking and socket cleanup
import net from 'net';
import { AsyncDeferer } from 'defer';

const defer = new AsyncDeferer();

const handleConnection = defer.wrapper((socket: net.Socket) => {
  // schedule a cleanup
  defer.defer(() => socket.end());

  // do some I/O
  socket.write('Hello from server!');
  // possibly more code ...
});
  1. Error recovery handling example :
import { SyncDeferer } from 'defer';

const faultyFunction = SyncDeferer.wrapper(() => {
  // schedule a deferred function that recovers from error
  SyncDeferer.defer(() => {
    const err = Deferer.recover();
    if (err) {
      console.log('Recovered from error:', err);
    }
  });

  // Now deliberately throw an error
  throw new Error('Something went wrong...');
});

// This call will NOT crash the program; it recovers inside the deferred function
faultyFunction();
console.log("Program continues after recovered error!");

/defer-node-js/

    Package Sidebar

    Install

    npm i defer-node-js

    Weekly Downloads

    6

    Version

    0.7.0

    License

    ISC

    Unpacked Size

    79 kB

    Total Files

    19

    Last publish

    Collaborators

    • ahmed.rakan