0

I have the following code.

However, it's not catching all errors and I am still getting "throw er; // Unhandled 'error' event".

Why is this?

app.post('/api/properties/zip/:zip/bedrooms/:bedrooms', async (req, res, next) => {
  try {
    const file = await apiCall(req.params.zip, req.params.bedrooms);
    const records = await parse(file);
    const seq = await sequelize();
    const result = await dbImport(seq, records);
    return await res.status(200).json(`${result.length} properties successfully imported to the database`);
  } catch (err) {
    return next(err);
  }
});

// Middleware error handling
app.use((err, req, res, next) => {
  console.error(err.message);
  if (!err.statusCode) err.statusCode = 500;
  return res.status(err.statusCode).json(err.message);
});

For example, it didn't catch the error in the parse() function, until I added a specific error handler. Shouldn't my try/catch catch this error even without adding this?

const fs = require('fs');

const parse = filename => new Promise(((resolve, reject) => {
  // Converts a line from the file, parses it to JSON, and stores it an array
  const func = (data, records) => {
    const json = JSON.parse(data);
    records.push(json);
  };

  // Read in each line of the file and pass that line to func
  const readLines = (input) => {
    const records = [];
    let remaining = '';


    // ******** HAD TO ADD THIS *********
    input.on('error', (err) => {
      reject(err);
    });


    input.on('data', (data) => {
      remaining += data;
      let index = remaining.indexOf('\n');
      let last = 0;
      while (index > -1) {
        const line = remaining.substring(last, index);
        last = index + 1;
        func(line, records);
        index = remaining.indexOf('\n', last);
      }
      remaining = remaining.substring(last);
    });

    input.on('end', () => {
      if (remaining.length > 0) {
        func(remaining, records);
      }
      resolve(records);
    });
  };

  const input = fs.createReadStream(filename);
  readLines(input, func);
}));

module.exports = parse;

Thanks in advance!

6
  • 1
    Is your question why you had to add the call to reject(...)? To settle your promise you must either call resolve or reject. Only by rejecting will you be able to catch the rejected (i.e. in the context of an await caller, thrown) value. Commented May 26, 2020 at 3:14
  • @chase thanks, I see. I thought it would catch all errors inside it whether they were sent to reject() or not. Commented May 26, 2020 at 3:23
  • 1
    If you are able to rewrite the promise as an async function, that will work as you expect (plus simplify the code). The issue only exists when you are working with the Promise primitives directly where you must explicitly call resolve or reject. Commented May 26, 2020 at 3:29
  • Ok sounds good. I will try that. And you can still call resolve and reject if you want to? Commented May 26, 2020 at 3:39
  • You mean if you make it an async function? If you change the Promise-returning function to instead be an async function there is no longer explicit resolve and reject. You either return a value (behaves like resolve) or an error is thrown (behaves like reject). See: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented May 26, 2020 at 3:55

1 Answer 1

1

Perhaps this will demonstrate for you how a try/catch will work with when using await. When a promise is rejected it will throw the resulting value. If the underlying promise resolves it will return that value.

(async () => {
  try {
    const val1 = await Promise.resolve('resolved val');
    const val2 = await Promise.reject('reject val');
    console.log(val1);
  } catch (err) {
    console.error(err);
  }
})();

Sign up to request clarification or add additional context in comments.

Comments

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.