JSFiddle - React, Tailwind, and code Playground

JavaScript

function CustomPromiseChain(events) {
  // Extract the main event and store it in its own variable
  const mainEvent = events.main;
  delete events.main;

  let eventHandlers = {};
  // Add functions to register the event handlers
  for (let eventName of Object.keys(events)) {
    this[eventName] = function (callback) {
      eventHandlers[eventName] = callback;
      return this;
    };
  }
  // Add the catch event handler
  eventHandlers.catch = function (err) {
    throw err;
  };
  this.catch = function (callback) {
    eventHandlers.catch = callback;
    return this;
  };

  // Here we wrap everything in a promise because
  // - The code will wait one tick so that the functions that register our event handlers will be called first
  // - We can catch all unhandled exceptions
  Promise.resolve()
    .then(() => {
      // Run all events, start with the main one
      mainEvent(function next(eventName, result) {
        // Call the event handler and go on with the next event if there's a valid return value
        if (
          ![undefined, false, null].includes(eventHandlers[eventName](result))
        ) {
          events[eventName](next, eventHandlers.catch);
        }
      }, eventHandlers.catch);
    })
    .catch(eventHandlers.catch);
}

// Example code:

function myCustomPromiseChain() {
  return new CustomPromiseChain({
    // The main event will always be called at first
    main(next, reject) {
      // This will call the next event with a result
      next('myEventOne', 'This is the result of event one.');
    },
    // Here you can register your other events:
    myEventOne(next, reject) {
      next('myEventTwo', 'This is the result of event two.');
    },
    myEventTwo(next, reject) {
      next('myEventThree', 'This is the result of event three.');
    },
    myEventThree(next, reject) {
      reject(new Error("I'm an error."));
    },
  });
}

myCustomPromiseChain()
  .myEventOne((result) => {
    console.log(`Result 1: ${result}`);
   ...