Search code examples
javascripterror-handlingfactory-pattern

Understanding factory error handler step-by-step


i'm reading and learning about promises/async/await. I'm a little stuck trying to understand step by step an error handling method that i already seen a couple of times, its a factory function approach for dealing with errors when creating promises.

Code with comments (questions below)


const myPromise = new Promise((resolve, reject)=> 
  setTimeout(()=> console.log('ERROR MESSAGE'),1000))

// async / await with error handler factory

 const testPromise = async () => {
     var data = await myPromise;
     console.log(data) 
}

// this is where i get stuck

const errorHandlerBig = function(fn){   // (1) 
  return function(...parameters) { // (2)
    return fn(...parameters).catch(function(err){ // (3) 
      console.error('Caught in Example 3:', err)
    })
  }
} 

errorHandlerBig(testPromise)(); 

  1. Takes testPromise as argument
  2. I debugged this and parameters content is [] (empty), when trying to assign a param to testPromise = async(paramName) => .... i can't work with it inside that function. what is it trying to spread?
  3. this is translated as testPromise(...params from previous step) i assume

Why is this chain of function calling-inside another function necesary?

Following with item (2), when trying to pass a value to paramName, it doesn't get printed on the console either!:

const testPromise = async (paramName) => {
     var data = await myPromise;
     console.log(data, paramName) 
}
const errorHandlerBig = function(fn){...}

errorHandlerBig(testPromise)('RandomValue')

Thank you everyone in advance!


Solution

  • errorHandlerBig is taking a function and wrapping it in its own error handling. From the outside in, it:

    1. Takes a function(1) as a parameter.
    2. Creates and returns a new function (2) that accepts any number of parameters.
    3. In function 2, calls function 1 using the parameters passed to function 2, and tries to catch any errors generated.

    Since errorHandlerBig is passing the parameters to fn, you would need testPromise to accept the parameters and log them if you expected them to appear in your console. Or you could throw them as an error in testPromise.

    As written, this isn't very useful, but it could be useful if you needed to make the same async process run more than once by saving the function returned by errorHandlerBig in a variable and calling that with different parameters, or if you wanted to use the same error handling behavior for multiple asynchronous processes.

    const throwThings = async (throwWhat) => {
      throw new Error(throwWhat);
    }
    
    const happyFunTimes = async (activity) => {
      console.log("I'm having fun");
      await setTimeout(() => console.log(`jumping on a ${activity}`), 1000);
    }
    
    const errorHandlerBig = function(fn){   // (1) 
      return function(...parameters) { // (2)
        return fn(...parameters).catch(function(err){ // (3) 
          console.error('Caught in Example 3:', err.toString())
        });
      }
    } 
    
    document.getElementById(":)").addEventListener("click", () => errorHandlerBig(happyFunTimes)("bananas"));
    document.getElementById(">:(").addEventListener("click", () => errorHandlerBig(throwThings)("bananas"));
    <button id=":)">Fun times</button>
    <button id=">:(">Throw</button>