Kashif Ghafoor
Kashif Ghafoor

Reputation: 386

is it good practice to use try inside try block to catch different errors? - JavaScript

I am using try catch inside try block to print relative message or get to know in which method error happened.

code snippet

  for (const searchUrl of savedSearchUrls) {
    console.log("here");
    // function will get all the links of profiles in saved search url
    try {
      const links = await scrapeFromurl(browser, searchUrl);
      try {
        saveToDatabase(links);
      } catch (e) {
        handleError(e, "eror while saving to database");
      }
    } catch (err) {
      handleError(err, "error in scrapeFromurl()");
    }
  }

I have searched on google but couldn't find related topic.

what are the other ways to accomplish similar things? what are the best practice to handle this type of situation.

Upvotes: 3

Views: 4556

Answers (3)

Lajos Arpad
Lajos Arpad

Reputation: 76426

By default a single try-catch block is enough without needs for nesting other try-catches into it. However, there may be some legitimate exceptions from these rules.

Exception 1: Different handlers for the same exception

Let's consider the following example

try {
  myroutine(); // may throw three types of exceptions
} catch (e) {
  if (e instanceof TypeError) {
    // statements to handle TypeError exceptions
  } else if (e instanceof RangeError) {
    // statements to handle RangeError exceptions
  } else if (e instanceof EvalError) {
    // statements to handle EvalError exceptions
  } else {
    // statements to handle any unspecified exceptions
    logMyErrors(e); // pass exception object to error handler
  }
}

It is perfectly possible that inside your try there is a section where a given error type, like a RangeError needs a different way of handling than the main catch. In this case it might make sense to have another try-catch inside your try, albeit, in this case, for better readability it would make sense to consider the inner try as a method and call that, so you would not physically nest the try-catch blocks, but separate the concerns of the try-catches into separate methods.

Exception 2: Handling a certain type of error only at a section of a try-block

It is quite possible that you want your try-catch to throw the error further in the majority of your try block, but, in a specific section you want it to handle it. Again, in this case it would make sense to separate the inner try into its own method.

Conclusion

Having nested try-catches are nonintuitive for a reader, therefore it makes sense to separate the inner try into its own method whenever you encounter the need to nest tries. Yet, as the examples above show, there are legitimate needs to drift away from the outer handling of an error for some sections. However, by default it is a good idea to consider such sections as separate concerns worthy of separating from the method. Of course, sometimes you might want to keep nested try-catches without separating their concerns, but more often than not it is worth to apply the separations. So, a rule of thumb that you may want to consider is to refactor nested try-catches either into separate methods or a single try-catch, unless there is a very good reason not to do so.

Upvotes: 3

Aziz Hakberdiev
Aziz Hakberdiev

Reputation: 326

In asyncronous scripts you can use domains for error handling. And trycatch in trycatch can be treated like domain in domain, which is pointless. Moreover, programmers always tend to prevent the code from growing horizontally like this

{
  ...
  {
    ...
    {
      ... (and so on)
      {
      }
    }
  }
}

So it is a really bad idea. I can keep on telling drawbacks of this approach, but not going to. Just use one trycatch with switchcase inside to handle all errors

Upvotes: -1

Mike
Mike

Reputation: 831

I would suggest using only one try catch block and specific error instances for each method, then in catch block you can simply check which method throws an error by using instanceof operator

class ScrapeError extends Error {
  message = "error in scrapeFromurl()"
}

class DBError extends Error {
  message = "eror while saving to database"
}

async function scrapeFromurl() {
  throw new ScrapeError();
}

async function saveToDatabase(links) {
  throw new DBError();
}

async function main() {
  try {
    const links = await scrapeFromurl();
    await saveToDatabase(links);
  } catch (e) {
  
    if (e instanceof ScrapeError) {
      console.log('scrape', e);
    }
    
    if (e instanceof DBError) {
      console.log('dberror', e);
    }
    
  }
}

main();

Upvotes: 3

Related Questions