1

(Please excuse my English)

I am learning about javascript promises, now. Below sample code is a simple javascript code for node.js(my node.js version is v10.0.0), which asynchronously reads and parses a JSON file using promise chain.

const fs = require("fs");

function readFileAsync(filename) {
    return new Promise((resolve, reject) => {
        fs.readFile(filename, 'utf8', (error, result) => {
            if (error)
                reject(error);
            else
                resolve(result);
        });
    });
}

readFileAsync('test.json')
    .then(res => JSON.parse(res))
    .then(res => { console.log('JSON=', res); })
    .catch(err => { console.log(err.message); });

I found that this sample code generates different formats of error messages. For example, if it cannot find 'test.json', the error message is...

ENOENT: no such file or directory, open '/home/node/test.json'

If it cannot parse 'test.json', the error message is...

Unexpected token / in JSON at position 31

I want to modify the sample code to generate same format of error message always containing JSON file name.
To do so, firstly I should know which part of promise chain caused error. How can I know?

pdh0710
  • 407
  • 1
  • 5
  • 14
  • Have you inspected error object to see if it isn't already there? – charlietfl May 06 '18 at 19:53
  • 1
    Have a look at [this](https://stackoverflow.com/a/26077868/1048572) and [that](https://stackoverflow.com/a/34748690/1048572) – Bergi May 06 '18 at 19:53
  • @charlietfl : Sorry I cannot understand your question clearly. Do you suggest [this](https://stackoverflow.com/a/26077569/7339376) or similar method? – pdh0710 May 06 '18 at 20:29
  • @Bergi : Thank you for your suggestion. I can find several methods to fit my purpose. I will try them. – pdh0710 May 06 '18 at 20:34

2 Answers2

2

There are two ways to arrived what you want.

Promise.then has two arguments, see below code and you can get more information here

readFileAsync('test.json')
    .then(res => JSON.parse(res))
    .then(res => { console.log('JSON=', res); }, error => {
      // here can catch error of previous then function
    });

Another way is modify the function readFileAsync

function readFileAsync(filename) {
    return new Promise(resolve => {
        fs.readFile(filename, (error, result) => {
            if (error)
                resolve(null); // you can resolve whatever you want
            else
                resolve(result);
        });
    });
}

And .catch() will not catch any error of readFileAsync.

Stephen Kingsley
  • 529
  • 1
  • 4
  • 9
0

Below sample code is a my solution. Thank you, Bergi and Stephen.
I choose this solution because I want to know exactly where in the chain the error occurred and what is the error.

const fs = require("fs");

function readFileAsync(filename) {
    return new Promise((resolve, reject) => {
        fs.readFile(filename, 'utf8', (error, result) => {
            if (error)
                reject(error);
            else
                resolve(result);
        });
    });
}

function readJsonAsync(filename, fnCallBack) {
    function fnMessage(n, str) {
        console.log(`[${n}:${filename}]`, str);
    }
    readFileAsync(filename)
        .then(
            res => JSON.parse(res),
            err => { fnMessage(-1, err.message); }
        ).then(
            res => {
                // if some errors occured at the previous step, res === undefined
                if (res !== undefined)
                    fnCallBack(filename, res);
            },
            err => { fnMessage(-2, err.message); }
        );
}

function printJSON(filename, json) {
    console.log(`JSON[${filename}]:`, json);
}

readJsonAsync('test.json', printJSON);

My solution has a prerequisite. The prerequisite is...

There is no simple way to break a promise chain even if some errors occured at previous steps of the chain.

Is this prerequisite right?

pdh0710
  • 407
  • 1
  • 5
  • 14