ловить ошибки MySQL перед отправкой ответа HTTP - PullRequest
0 голосов
/ 24 января 2019

Я пришел из php-фон, где SQL-запросы блокируются.

Моя обычная установка - сделать блок try, catch для обработки любых возможных ошибок, которые могут произойти во время обновления таблицы. Я хотел перенести эту логику на nodejs, но асинхронный характер делает это проблематичным. Взгляните на пример кода:

var httpServer = Https.createServer(httpsOptions, function (request, response) {


try {
     //many queries in if-else, switch statements
     if(something){
     mysqlConnection.query(query,[],function(err, result){});
     }else{
     //many queries will follow
       if(somethingelse){
        mysqlConnection.query(query2,[],function(err, result){});
       }else{
        mysqlConnection.query(query3,[],function(err, result){});
          if(andsoon){}
       }
     }

     response.writeHead(200, { "Content-Type": "text/plain" });
     response.end("Got it.");
     console.log("Response successful");
}catch(error){
     console.error(error);
     response.writeHead(400, { "Content-Type": "text/plain" });
     response.end("Error.");
}

}).listen(8000);

Итак, response.end() сработает до выполнения запроса, поэтому я отправляю сообщение, прежде чем узнаю, был ли запрос успешным. Я мог бы обернуть код response.end() в обратный вызов, но есть МНОГИЕ запросы, которые выполняются, так что теперь я должен отследить, сколько было выполнено до сих пор. Ситуация ухудшается: 1 поток управления if-else требует всего 1 запроса, другим - 10, поэтому отслеживание выполнения кода сводит с ума.

Это все не может быть оптимальным рабочим процессом. Что вы делаете, когда у вас сложная система запросов и вы хотите отправить ответ только после того, как все запросы выполнены (или не выполнены)?

1 Ответ

0 голосов
/ 24 января 2019

Вы добавили нулевые обратные вызовы из ваших вызовов .query.Это ваша проблема.

mysqlConnection.query(query,[],function(err, result){});
                               xxxxxxxxxxxxxxxxxxxxxxxx

Javascript продолжает выполнение следующего оператора после показанного немедленно, не дожидаясь завершения запроса .Вы знаете, что запрос завершен (или произошла ошибка) только тогда, когда метод .query вызывает вашу функцию обратного вызова.

Итак, вместо этого вам нужно сделать что-то подобное.

mysqlConnection.query(query,[],function(err, result){
    if (err) throw Error(err);
    //many queries will follow
    if(somethingelse){
           ...
    }
});

Последовательность запросов, которые вам нужны, заканчивается абсурдно глубоко вложенным набором функций обратного вызова.Но не отчаивайтесь: шаблон Promise в Javascript обойдется вам и даст вам чистый код.Используйте пакет обещаний-mysql npm .И напишите код, подобный этому.

    mysqlConnection.query(query,[])
    .then (function(mySqlConnection) {
         if (somethingelse) 
             return mysqlConnection.query(query2,[]) 
         else
             return mysqlConnection.query(query3,[]) 
         })
     .then (function(mySqlConnection) {
          return mysqlConnection.query(query4,[]) 
         })
     .then (function(mySqlConnection) {
          response.writeHead(200, { "Content-Type": "text/plain" });
          response.end("Got it.");
         })
     .catch (function(err)) {
          /* failure somewhere ! */
         });

У вас есть ряд функций затем с заглушкой в ​​конце.Подсистема Promise скрывает все вызовы обратного вызова для вас, упорядочивая их таким образом.(Обратите внимание, что я не отлаживал этот пример кода.)

Вы должны выяснить это Обещание вещи для успешного программирования sql / nodejs.Сначала это нелогично (по крайней мере, это было для меня, когда я изучал это).Но это стоит ваших усилий.Совет профессионала: если вы проходите через этот вид кода в отладчике, используйте Step Into свободно.

...