Node.js:如果传递的数据无效,应该拒绝并显示错误。

huangapple go评论78阅读模式
英文:

Node.js: should reject with an error if the passed data is invalid

问题

I'm getting a problem while running the test cases using the node.js application where I'm creating a directory if not exists, writing the json and reading the file.

Here's the Working Demo Link

It's throwing the below error even after handling the error in the code. I didn't get much help from other solutions related to Promise rejection in Stackoverflow. Looking for a working solution. I'm getting the below issue after doing npm test:

should reject with an error if the passed data is invalid:

Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Promise
  at TypeError.get (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:385021)
  at EventEmitter.emit (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:143926)
  at process.onGlobalUncaughtException [as _fatalException] (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:363886)
  at triggerUncaughtException (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:42:367400)
  at processPromiseRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:1794051)
  at processTicksAndRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:801887)
  at _0x263935 (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:37:263515)

While doing npm start I'm getting the below problem:

Server running at http://127.0.0.1:3000/
Error: Invalid data
    at writeJSON (file:///home/projects/stackblitz-starters-xzxhal/index.js:70:15)
    at Server.eval (file:///home/projects/stackblitz-starters-xzxhal/index.js:24:15)
TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Promise
    at TypeError.get (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:385021)
    at triggerUncaughtException (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:42:367449)
    at processPromiseRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:1794051)
    at processTicksAndRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:801887)
    at _0x263935 (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:37:263515) {
  code: 'ERR_INVALID_ARG_TYPE'
}

Here's my index.js file code pieces:

const server = http.createServer(async (req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    const dirPath = DIR_PATH + dirs[0];
    const filePath = dirPath + './data.json';
    let createdDirectoryIfNotExists = await createDirectoryIfNotExists(filePath);
    if (createdDirectoryIfNotExists) {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.write(writeJSON('./temp', contents));
        res.end();
    }
});

// write json in file
const writeJSON = async (filePath, contents) => {
    try {
        if (contents && typeof contents === "object") {
            const jsonString = JSON.stringify(contents);
            // write file 
            let isWriteFileSynced = fs.writeFileSync(filePath, jsonString, error => {
                if (error) {
                    console.log(error);
                } else {
                    return jsonString;
                }
            })
            if (isWriteFileSynced) {
                // read file after file is written
                let isReadFileSynced = fs.readFileSync(filePath, "utf8", (error, jsonString) => {
                    if (error) {
                        return false;
                    } else {
                        return jsonString;
                    }
                })

                // if read file, return the jsonString
                if (isReadFileSynced) {
                    return jsonString;
                }
            } else {
                throw new Error("Invalid data");
            }
            return jsonString;
        }
    } catch (error) {
        console.log(error);
        return;
    }

};


// create directory if not exists
const createDirectoryIfNotExists = async (path) => {
    fs.mkdirSync(path, { recursive: true });
    return true;
};

How to solve this issue?

英文:

I'm getting a problem while running the test cases using the node.js application where I'm creating a directory if not exists, writing the json and reading the file.

Here's the Working Demo Link

It's throwing the below error even after handling the error in the code. I didn't get much help from other solutions related to Promise rejection in Stackoverflow. Looking for a working solution. I'm getting the below issue after doing npm test:

should reject with an error if the passed data is invalid:

Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Promise
  at TypeError.get (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:385021)
  at EventEmitter.emit (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:143926)
  at process.onGlobalUncaughtException [as _fatalException] (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:363886)
  at triggerUncaughtException (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:42:367400)
  at processPromiseRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:1794051)
  at processTicksAndRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:801887)
  at _0x263935 (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:37:263515)

While doing npm start I'm getting the below problem:

Server running at http://127.0.0.1:3000/
Error: Invalid data
    at writeJSON (file:///home/projects/stackblitz-starters-xzxhal/index.js:70:15)
    at Server.eval (file:///home/projects/stackblitz-starters-xzxhal/index.js:24:15)
TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Promise
    at TypeError.get (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:385021)
    at triggerUncaughtException (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:42:367449)
    at processPromiseRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:1794051)
    at processTicksAndRejections (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:35:801887)
    at _0x263935 (https://stackblitzstartersxzxhal-cstc.w-credentialless.staticblitz.com/blitz.a19575a2.js:37:263515) {
  code: 'ERR_INVALID_ARG_TYPE'
}

Here's my index.js file code pieces:

const server = http.createServer(async (req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    const dirPath = DIR_PATH + dirs[0];
    const filePath = dirPath + './data.json';
    let createdDirectoryIfNotExists = await createDirectoryIfNotExists(filePath);
    if (createdDirectoryIfNotExists) {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.write(writeJSON('./temp', contents));
        res.end();
    }
});

// write json in file
const writeJSON = async (filePath, contents) => {
    try {
        if (contents && typeof contents === "object") {
            const jsonString = JSON.stringify(contents);
            // write file 
            let isWriteFileSynced = fs.writeFileSync(filePath, jsonString, error => {
                if (error) {
                    console.log(error);
                } else {
                    return jsonString;
                }
            })
            if (isWriteFileSynced) {
                // read file after file is written
                let isReadFileSynced = fs.readFileSync(filePath, "utf8", (error, jsonString) => {
                    if (error) {
                        return false;
                    } else {
                        return jsonString;
                    }
                })

                // if read file, return the jsonString
                if (isReadFileSynced) {
                    return jsonString;
                }
            } else {
                throw new Error("Invalid data");
            }
            return jsonString;
        }
    } catch (error) {
        console.log(error);
        return;
    }

};


// create directory if not exists
const createDirectoryIfNotExists = async (path) => {
    fs.mkdirSync(path, { recursive: true });
    return true;
};

How to solve this issue?

答案1

得分: 1

Here is the translated code:

那个错误来自于`writeJSON`它返回未解决的Promise因此出现了错误

所以你需要等待它

res.write(await writeJSON('./temp', contents));

但是正如评论中指出的那样你在函数内部使用了同步方法所以不需要返回Promise也不需要在`writeJSON`函数上使用`async`

此外`fs.writeFileSync`不接受回调函数它返回`undefined`所以检查部分将始终失败

它会抛出异常因此你需要将`fs`的两个方法都包装在`try/catch`并从`try`部分返回JSON

此外不清楚为什么在之后读取文件如果没有抛出异常它就已经被写入了但你可以重新组织一下

这是一个应该可以工作的起始点在某种程度上):

const writeJSON = (filePath, contents) => {
  try {
    if (contents && typeof contents === 'object') {

      const jsonString = JSON.stringify(contents);

      // 写入文件
      try {

        fs.writeFileSync(
          filePath,
          jsonString
        );


        // 文件写入后读取文件
        let isReadFileSynced = fs.readFileSync(
          filePath,
          'utf8'

        );


        // 如果读取文件,返回jsonString
        if (isReadFileSynced) {
          return jsonString;
        }

      } catch (err) {
        console.log(err);
      }


    } else {
      throw new Error('无效的数据');
    }

  } catch (error) {
    console.log(error);
    return;
  }
};

修订后的测试通过的函数:

const writeJSON = async (filePath, contents) => {
 
    if (contents && typeof contents === 'object') {
      const jsonString = JSON.stringify(contents);

      // 写入文件
      try {
        fs.writeFileSync(filePath, jsonString);

        // 文件写入后读取文件
        let isReadFileSynced = fs.readFileSync(filePath, 'utf8');

        // 如果读取文件,返回jsonString
        if (isReadFileSynced) {
          return jsonString;
        }
      } catch (err) {
        console.log(err);
        // 待办事项
        throw new Error('写入错误');
      }
    } else {
      throw new Error('无效的数据');
    }

};
英文:

That error comes from writeJSON, which returns unresolved Promise, hence the error

So, you need to await it:

res.write(await writeJSON('./temp', contents));

But, as pointed out in the comments, you use sync methods within the function, so no need to return a Promise, so no need to use async on writeJSON function

Also, fs.writeFileSync does not take a callback, and it returns undefined, so the check part will always fail.

It throws, so you need to wrap both fs methods in try/catch, and return json from the try part.

Also, not sure why you read the file afterwards, if it didn't throw, it's written but you can reorganize that:

Here's a starter that should work (somewhat):

const writeJSON = (filePath, contents) => {
try {
if (contents && typeof contents === 'object') {
const jsonString = JSON.stringify(contents);
// write file
try {
fs.writeFileSync(
filePath,
jsonString
);
// read file after file is written
let isReadFileSynced = fs.readFileSync(
filePath,
'utf8'
);
// if read file, return the jsonString
if (isReadFileSynced) {
return jsonString;
}
} catch (err) {
console.log(err);
}
} else {
throw new Error('Invalid data');
}
} catch (error) {
console.log(error);
return;
}
};

edit

tests passing function:

const writeJSON = async (filePath, contents) => {
if (contents && typeof contents === 'object') {
const jsonString = JSON.stringify(contents);
// write file
try {
fs.writeFileSync(filePath, jsonString);
// read file after file is written
let isReadFileSynced = fs.readFileSync(filePath, 'utf8');
// if read file, return the jsonString
if (isReadFileSynced) {
return jsonString;
}
} catch (err) {
console.log(err);
// todo
throw new Error('err writing');
}
} else {
throw new Error('Invalid Data');
}
};

huangapple
  • 本文由 发表于 2023年6月29日 15:47:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76579021.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定