【问题标题】:Node Sqlite3 Errors节点 Sqlite3 错误
【发布时间】:2020-09-30 07:51:22
【问题描述】:

我在 node 中使用 sqlite3 包并开始清理我的 REST API。我决定在数据库调用和控制器中创建一个承诺包装器,使用 async/await 来调用这些函数并将返回值设置为一个变量。然后,检查变量并设置响应对象。对于成功案例,它运行良好,找到了一个东西并设置了响应。问题是,在 SQLITE3 中我很难检查错误。我在 DB 服务中对 undefined 进行了基本检查,如果遇到错误,它确实会引发错误,但是该错误会立即转到控制器的 CATCH 部分,并且不允许我将其包装在我想要的 API 响应中喜欢定义。这些是单独的文件(控制器与服务)。我没有找到很多关于 sqlite3 错误检查的有用信息,那里很少。理想情况下,该服务会抛出一个错误,然后我可以将其包装到一个标准化的响应对象中并发送。

------位置

const getById = async (req, res, next) => {
    response = {};
    try {
        let location = await getLocationById(req.params.id); // <-- IF NO VALUE FOUND, location IS nothing
        if (error) { // <----- THIS IS WHERE I'D LIKE TO CHECK FOR ERRORS.
            response.status = 404;
            response.message = 'Error attempting to get location';
        } else {
            response.status = 200;
            response.message = 'Success';
            response.data = location;
        }
        res.json(response);
    } catch (error) {
        res.json(response);
    }
};

------------ 服务

const getLocationById = (id) => {
    return new Promise((resolve, reject) => {
        let sql = 'SELECT * FROM Locations WHERE id = ?;';
        db.get(sql, [id], (error, location) => {
            if (location !== undefined) {
                resolve(location);
            } else {
                reject(new Error('Error attempting to get location by id'));
            }
        });
    });
};

【问题讨论】:

    标签: node.js node-sqlite3


    【解决方案1】:

    您只需将对getLocationById() 的调用封装在另一个try/catch 中。从那里您可以决定是否要包装或引发错误。如果您没有要添加的其他代码可能会引发错误,您可以删除外部try/catch。内联 cmets 中的更多解释和建议:

    const getLocationById = (id) => {
      return new Promise((resolve, reject) => {
        const sql = "SELECT * FROM Locations WHERE id = ?;";
        db.get(sql, [id], (error, location) => {
          // check for an error from the db here
          if (error) return reject(error);
          // check for an empty result here and throw your own error
          if (!location) {
            // set a property so we can tell that it wasn't a db error just not found
            const myError = new Error("Error attempting to get location by id");
            myError.notFound = true;
            return reject(myError);
          }
          // otherwise resolve the result
          return resolve(location);
        });
      });
    };
    
    const getById = async (req, res, next) => {
      // use const since it is not reassigned, only properties are changed
      const response = {};
      try {
        // code here that might throw an exception
        try {
          // use const if you aren't going to reassign `location`
          const location = await getLocationById(req.params.id); 
          
          // we were able to load the location if we get here
          response.status = 200;
          response.message = "Success";
          response.data = location;
        } catch (error) {
          // maybe check to see if we want to wrap or raise the error
          // maybe call console.log(error) to see the contents
          const doWeWantToWrapTheError = somethingToCheckTypeEtc(error);
          if (doWeWantToWrapTheError) {
            if (error.notFound) {
              // no db errors, just not found
              response.status = 404;
            } else {
              // some kind of db error so set to "internal server error"
              response.status = 500;
            }
            response.message = "Error attempting to get location";
          } else {
            // raise the error to the outer try/catch
            throw error;
          }
        }
        // code here that might throw an exception
        return res.json(response);
      } catch (unexpected) {
        // some other error occurred that was not caught above (unlikely)
        // maybe call console.log(unexpected) to see the contents
        response.error = unexpected.message;
        return res.json(response);
      }
    };
    
    

    【讨论】:

    • 这是有道理的。尝试标准化错误报告是一项挑战。 get 子句很好,更新操作太令人沮丧了。无论项目是否更新,我都会得到一个“this”返回值,它在返回值中不是离散的,更新返回值 1,未更新返回值 1。难以破译
    • @mikevarela 听起来try/catch 也会成为你的朋友。如果您包装更新,您可以判断它是否有效 - 更高级一些,但如果也有错误,您可以使用事务回滚任何更改。不过可能最好发布一个新问题:)
    • 谢谢。一直在使用 double try catch 块,现在运行良好。好像有点绕。但至少它按预期工作。
    • @mikevarela 如果您知道代码不会引发异常,则不必使用嵌套的try/catch。我在回答中使用了它作为示例,但请检查 cmets,其中显示“此处可能引发异常的代码” - 如果您没有任何内容,您可以只使用一次 try catch。
    • 我的问题是当事情不工作时我想抛出错误。然后在主控制器的错误部分,拾取该错误并将其放入标准响应对象中。该响应对象用于成功和错误输出。我想向对象添加状态错误代码,因此仅靠错误消息是不够的。我发现在 await 函数中,错误会导致失败并发送消息。但我想要一个状态码。所以我试图先捕捉错误,然后用更多的自定义信息重新触发它。现在大声思考,这可能是使用自定义错误的地方
    猜你喜欢
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 2015-05-02
    • 2017-10-05
    • 2018-11-29
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多