0

Let's assume I have this pseudocode inside a routes.js file:

var pkg = require('random-package');

app.post('/aroute', function(req, res) {
    pkg.impl_func(data, function (err, result) {
        myFunction(entity).then(user=>{
            //DO_STUFF_HERE
            res.render('page.ejs');
        }).catch(err => {
            console.log(err);
            res.render('error.ejs');
        });
    });
});

function myFunction(username) {
   //.....
}

The pkg I used is one found on the npmjs website. myFunction() is always my function.

In my code you can see that i have implemented then/catch statement for when myFunction() fails. So when that happens error.ejs is rendered.

But what happens when the npm package fails? In the terminal i get the error message but there is no error handling on the server side. This means, when it fails the user will not be notified with error.ejs, it is obvious since this functionality is omitted from my code.

But what are the ways to render error.ejs, when pkg fails?

Since I am already using .then()/.catch() technique below, can I also do it above? In other words, can I nest .then()/.catch() statements? Can I surround the outer code to a try/catch (while still having a try/catch inside)?

0

2 Answers 2

2

pkg.impl_func() appears to implement your typical Node.js callback interface (i.e. it returns an error as first argument in the event of an error or null if there's no error). You can simply check for the error's presence and render your error.ejs when it is present:

app.post('/aroute', function(req, res) {
  pkg.impl_func(data, function (err, result) {
    if (err) {
      res.render('error.ejs');
    } else {
      myFunction(entity).then(user=>{
        //DO_STUFF_HERE
        res.render('page.ejs');
      }).catch(err => {
        console.log(err);
        res.render('error.ejs');
      });
    }
  });
});

Alternatively, you can use util.promisify() to convert pkg.impl_func() into an async function. Then you can use promise.catch() or try-catch inside an async function to simplify the syntax:

const util = require('util')
const impl_func_async = util.promisify(pkg.impl_func)

// traditional promises:
app.post('/aroute', (req, res) => {
  impl_func_async(data).then(result =>
    return myFunction(entity)
  }).then(user => {
    // DO_STUFF_HERE
    res.render('page.ejs')
  }).catch(e => {
    // Will catch thrown errors from impl_func_async and myFunction
    console.log(e)
    res.render('error.ejs')
  })
})

// async-await:
app.post('/aroute', async (req, res) => {
  try {
    const result = await impl_func_async(data)
    const user = await myFunction(entity)
    // DO_STUFF_HERE
    res.render('page.ejs')
  } catch (e) {
    // Will catch thrown errors from impl_func_async and myFunction
    console.log(e)
    res.render('error.ejs')
  }
})
Sign up to request clarification or add additional context in comments.

Comments

0

You could use a simple try/catch to wrap it all and render error.js in that catch also.

As for nesting try/catch...yes you can. In this case however a promise catch() is slightly different than a basic try/catch

app.post('/aroute', function(req, res) {

      try {
        pkg.impl_func(data, function(err, result) {
          myFunction(entity).then(user => {
            //DO_STUFF_HERE
            res.render('page.ejs');
          }).catch(err => {
            console.log(err);
            res.render('error.ejs');
          });
        });

      } catch (e) {
        res.render('error.ejs');
      }
    });
});

1 Comment

Thanks but i tried this and it didn't work. The error was thrown - as evident in the terminal, but there was no redirect to 'error.ejs'. (BTW, in your code you have one more pair of '});' that it is required.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.