mysql - NodeJs 异步库:为什么发生错误后没有触发回调?
问题描述
我一直在开发 NodeJS 服务器的后端,该服务器当前使用库“async”和“mysql”。请注意,这三个例程在 async 的“瀑布”函数中执行。它应该按如下方式工作:
- 服务器连接到 MySQL 数据库
- MySQL 数据库在表“标签”中插入一个新条目
- 如果服务器尝试插入重复项,则应引发错误并且测试应失败
- 服务器与 MySQL 数据库断开连接
不幸的是,即使服务器的 MySQL 客户端尝试插入重复项,我使用 mocha 运行的每个测试仍然通过。
我已经阅读了库“异步”的文档。它表示如果在“瀑布”函数执行过程中发生错误,控制流将被重定向到“瀑布”回调。我还尝试查阅“mysql”库的文档。但我找不到任何可以帮助我解决问题的东西。我应该将可能引发错误的代码放在 try-catch 块中还是必须发出特殊的回调?
文件:SqlTagsTest.js
var mysql = require('mysql');
var mySqlUtils = require('../../backend/MySqlHandler/MySqlUtils.js');
var mySqlTags = require('../../backend/MySqlHandler/MySqlTags.js');
describe('Create new tag',function(){
var connection = "";
var queryParams = "";
before(function(done){
connection = mysql.createConnection({
host:'myHost',
user:'root',
password:'myPassword',
database:'myDb'
});
queryParams = {
name: 'Tag',
description: 'Description',
parent: 'root',
creator: 'me',
admin: false
};
done();
});
it('should create a new tag inside the database',function(){
mySqlTags.CreateTag(connection,queryParams);
});
文件:MySqlTags.js
var sqlUtils = require('./MySqlUtils.js');
var reflectChanges = require('./MySqlReflection.js');
var async = require('async');
function CreateTag(connection,queryParams){
async.waterfall([
function SetupData(callback){
callback(null,connection,queryParams);
},
sqlUtils.ConnectToDatabase,
sqlUtils.InsertTagIntoDatabase,
sqlUtils.CloseDatabaseConnection
],function(err,results){
if(err)
{
throw err;
}
});
}
function DeleteTag(connection,queryParams,serverResponse){
async.waterfall([
function setupData(callback){
callback(null,connection,queryParams);
},
sqlUtils.ConnectToDatabase,
reflectChanges.DeleteTagEntry,
reflectChanges.GenerateUncategorizedTag,
reflectChanges.UpdateChildrensParent,
sqlUtils.CloseDatabaseConnection
],function(error,results){
if(error){
serverResponse(queryParams,error,false);
}else{
serverResponse(queryParams.name,true);
}
});
}
function EditTag(queryParams,serverResponse){
async.waterfall([
sqlUtils.ConnectToDatabase,
sqlUtils.CloseDatabaseConnection
],function(error,results){
if(error){
serverResponse(queryParams.name,false);
}else{
console.log("No errors!");
serverResponse(queryParams.name,true);
}
});
}
module.exports = {
CreateTag: CreateTag,
DeleteTag: DeleteTag,
EditTag: EditTag
}
文件:MySqlUtils.js
var mySql = require('mysql');
var reflectChanges = require('./MySqlReflection.js');
var async = require('async');
/**
* connects to a MySql database
* @param {connection which will be established} connection
* @param {paremeters which are executed} queryParams
* @param {callback which is required by the async library} callback
*/
function ConnectToDatabase(connection,queryParams,callback){
connection.connect(function(error){
if(error){
console.log(error);
throw error;
}else{
callback(null,connection,queryParams);
}
});
}
/**
* closes an existing connection to the MySql database
* @param { connection which is passed from the previous function } connection
* @param { callback when database connection was successfully closed } callback
*/
function CloseDatabaseConnection(connection,queryParams,callback)
{
connection.end(function(error)
{
if(error){
throw error;
}else{
callback(null,connection,queryParams);
}
});
}
/**
* get all files which will be affected by the particular query
* @param {*} connection
* @param {*} queryParams
* @param {*} callback
*/
function GetAffectedFiles(connection,queryParams,callback)
{
const query = "SELECT Name,Tags FROM Tag";
const params = [];
var affectedRows = [];
connection.query(query,params,function(error,results,fields){
if(error){
return connection.rollback(function(){
throw error;
});
}else{
for(var currRow = 0; currRow < results.length; currRow++)
{
if(results[currRow].Name === queryParams.name){
affectedRows.push(results[currRow].Name);
}
}
}
queryParams.affectedRows = affectedRows;
callback(connection,queryParams,callback);
});
}
/**
* inserts a new tag into the database
* @param { connection which will be passed from the previous function } connection
* @param { field values of the original row } queryParams
* @param { callback called when query was executed successfully } callback
*/
function InsertTagIntoDatabase(connection,queryParams,callback){
const query = "INSERT INTO Tag(Id,Name,Description,Parent,Creator,Admin) VALUES((SELECT UUID()),?,?,?,?,?)";
const params = [queryParams.name,queryParams.description,queryParams.parent,queryParams.creator,queryParams.admin];
connection.query(query,params,function(error,results,fields){
if(error){
throw error;
throw error;
}else{
callback(null,connection,queryParams);
}
});
}
/**
* process chain which allows will be triggered upon tag deletion
* @param { connection which was established between } connection
* @param { queryParameters which will be passed to subroutines } queryParams
* @param { callback which will be called upon termination } callback
*/
function ReflectTagRemoval(connection,queryParams,callback){
async.waterfall([
function SetupPrequisites(callback){
callback(null,connection,queryParams);
},
reflect.DeleteTagEntry,
reflect.UpdateChildrenTag,
reflect.UpdateFileTags,
function PassFurther()
{
callback(null,connection,queryParams);
}
]);
}
function ReflectTagUpdate(connection,queryParams,callback){
async.waterfall([
function SetupPrequisites(callback){
callback(null,connection,queryParams);
},
ConnectToDatabase,
reflectChanges.EditTagEntry,
reflectChanges.EditTagChildrenAfterChanges,
reflectChanges.UpdateFileTagsAfterEdit,
function PassFurther(callback){
callback(null,connection,queryParams);
}
]);
}
function ValidateLoginCredentials(connection,loginCredentials,callback)
{
const query = "SELECT Name,Password FROM User WHERE Name = ? AND Password = ?";
const params = [loginCredentials.username,loginCredentials.password];
connection.query(query,params,function(error,results,fields){
if(error)
{
throw error;
}
callback(null,connection);
});
}
module.exports =
{
ConnectToDatabase: ConnectToDatabase,
InsertTagIntoDatabase: InsertTagIntoDatabase,
ReflectTagRemoval: ReflectTagRemoval,
ReflectTagUpdate: ReflectTagUpdate,
ValidateLoginCredentials: ValidateLoginCredentials,
CloseDatabaseConnection : CloseDatabaseConnection
}
解决方案
推荐阅读
- powershell - 从类型为 system.string 的变量中读取值
- python - 如何拆分字符串?
- date - 使用选择值将 Epoch 转换为 Date
- drupal - 如何在视图中搜索多个值字段?
- r - 根据日期和初始事件识别重复 ID 的后续事件
- android - 如何录制whatsapp语音通话,例如手机模拟通话录音?
- sql - 当信息在列中时,仅将两个表中的一个表信息返回到行中
- python - 在 Windows 上,即使在 pip install 或 conda 之后,graphviz 也无法正常工作。它说 InvocationException: GraphViz's executables not found
- c++ - 实现交换/复制功能:有更好的方法吗?
- javascript - Mongoose 从 html datepicker 中查找 2 个日期之间的结果