节点 Sqlite3 错误
Node Sqlite3 Errors
我在节点中使用 sqlite3 包并开始清除我的 REST API。我决定围绕数据库调用和控制器创建一个承诺包装器,使用 async/await 调用这些函数并将该 return 值设置为一个变量。然后,检查变量并设置响应对象。对于成功案例,它运行良好,找到了一个东西并设置了响应。问题是,在 SQLITE3 中我很难检查错误。我对数据库服务中的未定义进行了基本检查,如果遇到错误,它会抛出错误,但该错误会立即进入控制器的 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'));
}
});
});
};
您只需将对 getLocationById()
的调用包装在另一个 try/catch
中。从那里您可以决定是要包装还是引发错误。如果您没有要添加的其他代码可能会引发错误,您可以删除外部 try/catch
。在线评论中的更多解释和建议:
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);
}
};
我在节点中使用 sqlite3 包并开始清除我的 REST API。我决定围绕数据库调用和控制器创建一个承诺包装器,使用 async/await 调用这些函数并将该 return 值设置为一个变量。然后,检查变量并设置响应对象。对于成功案例,它运行良好,找到了一个东西并设置了响应。问题是,在 SQLITE3 中我很难检查错误。我对数据库服务中的未定义进行了基本检查,如果遇到错误,它会抛出错误,但该错误会立即进入控制器的 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'));
}
});
});
};
您只需将对 getLocationById()
的调用包装在另一个 try/catch
中。从那里您可以决定是要包装还是引发错误。如果您没有要添加的其他代码可能会引发错误,您可以删除外部 try/catch
。在线评论中的更多解释和建议:
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);
}
};