skip to Main Content

I’ve been reading Callback Hell, which states:

With callbacks the most popular way to handle errors is the Node.js style where the first argument to the callback is always reserved for an error.

and gives this example:

 var fs = require('fs')

 fs.readFile('/Does/not/exist', handleFile)

 function handleFile (error, file) {
   if (error) return console.error('Uhoh, there was an error', error)
   // otherwise, continue on and use `file` in your code
 }

My functions look differenty, something like ths

function example (varA, varB){
    //...
    try{
       //...
    }catch {
       //...
    }
}

where varA and varB are variables/arguments used to do stuff inside the function. Now, if I would change the code to function example (error, varA, varB), how would I pass the variables, since the first expected argument is actually an error.

If anyone can please provide an example or/and provide some good reading it would be most welcome.

Thank you

2

Answers


  1. Now, if I would change the code to function example (error, varA, varB), how would I pass the variables…

    I’m assuming you mean that you’re writing an API that will accept callback functions with that kind of signature. If so, on success you call it with null as the first parameter, as that’s the convention in these callback-style APIs. (And on failure you’e call it with an error as the first parameter, and typically no other parameters.)

    // Your API function
    function doSomething(param, callback) {
        // There's no point to this style unless the work is asynchronous, so:
        setTimeout(() => {
            if (param.includes("good")) {
                // Success
                callback(null, 1, 2);
            } else {
                // Error
                callback(new Error(`Using param ${param} failed`));
            }
        }, 100);
    }
    
    // The callback we'll use
    const fn = (error, x, y) => {
        if (error) {
            console.error(error);
        } else {
            console.log(`x: ${x}, y: ${y}`);
        }
    };
    
    // Example of successful call:
    doSomething("good", fn);
    
    // Example of unsuccessful call:
    doSomething("bad", fn);

    But asynchronous callback-style APIs of this kind are obsolete. Instead, use promises, directly or indirectly via async functions.

    // Your API function
    function doSomething(param, callback) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (param.includes("good")) {
                    // Success
                    resolve([1, 2]);
                } else {
                    // Error
                    reject(new Error(`Using param ${param} failed`));
                }
            }, 100);
        });
    }
    
    // The fulfillment and rejection callbacks we'll use
    const onFulfilled = ([x, y]) => {
        console.log(`x: ${x}, y: ${y}`);
    };
    const onRejected = (reason) => {
        console.error(reason);
    };
    
    // Example of successful call:
    doSomething("good").then(onFulfilled, onRejected);
    
    // Example of unsuccessful call:
    doSomething("bad").then(onFulfilled, onRejected);
    
    // Examples in an `async` function instead of `onFulfilled`/`onRejected`
    async function usingApi(param) {
        try {
            const [x, y] = await doSomething(param);
            console.log(`x: ${x}, y: ${y}`);
        } catch (error) {
            console.error(error);
        }
    }
    setTimeout(() => { // Just so we know the earlier examples have finished
        usingApi("good").then(() => usingApi("bad"));
    }, 400);
    .as-console-wrapper {
        max-height: 100% !important;
    }
    Login or Signup to reply.
  2. It depends of what you want.

    1. Someone calls your function. You function can return sync result – error is not needed here. (callback context). If your function is async, then you request cb function as last argument
    function example (varA, varB, cb){
        //...
        try{
           cb(null, varA+varB)
        }catch (e) {
           cb(e, null)
        }
    }
    

    In that case you pass the err to the calling code, cuz it is common contract.

    With callbacks the most popular way to handle errors is the Node.js style where the first argument to the callback is always reserved for an error.

    example(1, 2, (err, result) => {
      if (err) {}
      else {
        result is valid
      }
    })
    
    1. Function from our example is just regular function => there are not necessary to work with err arg. Just return return as usual.

    Callback uses for async operations. These operation can be finished with error and first err argument is a common way to say you "we have a problem"

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search