Асинхронная библиотека NodeJs: почему не происходит обратный вызов после возникновения ошибки? - PullRequest
0 голосов
/ 19 декабря 2018

Я разрабатывал серверную часть сервера NodeJS, который в настоящее время использует библиотеки «async» и «mysql».Обратите внимание, что эти три подпрограммы выполняются внутри функции асинхронного «водопада».Он должен работать следующим образом:

  • Сервер подключается к базе данных MySQL
  • База данных MySQL вставляет новую запись в таблицу 'Tag'
    • , если сервер пытаетсявставьте дубликат, должно быть выдано сообщение об ошибке, и проверка должна завершиться неудачейНесмотря на то, что клиент MySQL сервера пытается вставить дубликат.

      Я уже прочитал документацию для библиотеки 'async'.Он сказал, что поток управления будет перенаправлен на обратный вызов «водопад», если во время выполнения функции «водопад» произойдет ошибка.Я также попытался обратиться к документам библиотеки "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
      }
      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...