Klaus1: node.js und promise-mysql: Wie Fehlerbehandlung?

Hallo,

folgender Code funktioniert soweit erstmal einwandfrei:

var mysql = require( 'promise-mysql' );

var pool  = mysql.createPool({
	host: "localhost",
	user: "user",
	password: "gaaanzgeheim",
	database: "datenbank",
});

param1 = 23;
param2 = 70;
param3 = 162;
param4 = 295;

pool.getConnection()
	.then(connection => {
		connection.query('select data from werte where idnr = ?', param1)
		.then( (rows1) => {
			console.log(param1+": "+rows1[0].data);
			return connection.query('select data from werte where idnr = '+param2);
		})
		.then( (rows2) => {
			console.log(param2+": "+rows2[0].data);
			return connection.query('select data from werte where idnr = '+param3);
		})
		.then( (rows3) => {
			console.log(param3+": "+rows3[0].data);
			return connection.query('select data from werte where idnr = '+param4);
		})
		.then( (rows4) => {
			console.log(param4+": "+rows4[0].data);
		})
	})

console.log("fertig");

Die Frage ist nun, wie ich hier sinnvoll eine Fehlerbehandlung einbaue. Da es nur Selects sind, muss ich schonmal kein "beginTransaction" oder so verwenden. Aber wenn z.B. ein Eintrag nicht gefunden wird, dann bricht mir das Script ab mit dem Fehler: "Unhandled rejection TypeError".

Jetzt könnte ich wohl jedes Kommando mit einem Try {} Catch {} klammern. Oder in jedes Query das Errorhandling einbauen:

connection.query('select data from werte where idnr='+param1, function (err, rows) {
    if (err) throw new Error(err)
})

Oder die Variable prüfen:

if (!rows[0].data) {
	throw err;
}

Oder ein .catch(err) an jedes Ende vom .then einbauen?

Was denkt ihr? Was ist die sinnvollste und lesbarste Form der Fehlerbehandlung?

LG Klaus

  1. Tach!

    Die Frage ist nun, wie ich hier sinnvoll eine Fehlerbehandlung einbaue. [...] wenn z.B. ein Eintrag nicht gefunden wird, dann bricht mir das Script ab mit dem Fehler: "Unhandled rejection TypeError".

    Jetzt könnte ich wohl jedes Kommando mit einem Try {} Catch {} klammern.

    Kannst du, dürfte aber nicht funktionieren im Zusammenhang mit Promises / asynchronen Callbacks. Lediglich innerhalb einer Funktion wird das erfolgreich sein.

    Oder in jedes Query das Errorhandling einbauen:

    connection.query('select data from werte where idnr='+param1, function (err, rows) {
        if (err) throw new Error(err)
    })
    

    Das wäre eine Variante. Soweit ich sehe, ist das die Variante von mysqljs

    Oder ein .catch(err) an jedes Ende vom .then einbauen?

    Das geht auch. Aber nur mit promise-mysql?

    Oder die Variable prüfen:

    if (!rows[0].data) {
    	throw err;
    }
    

    Damit prüfst du nicht auf Fehler sondern auf die Folgen eines Fehlers. Prüf doch lieber direkt.

    Was denkt ihr? Was ist die sinnvollste und lesbarste Form der Fehlerbehandlung?

    Lesbar ist Fehlerbehandlung selten. Bläht den meisten Code mehr auf als die eigentliche Arbeit. Nur weglassen ist auch keine Option.

    dedlfix.

    1. Die Fehlerbehandlung direkt in das Query einzubauen, wäre auch meine favorisierte Variante, ich weiß nur nicht recht, wie ich mit meinem Code verheirate.

      Ich habs jetzt so versucht, aber das gibt nur noch "fertig" aus. Mehr nicht mehr:

      mysqlPool.getConnection()
      	.then(connection => {
      		connection.query('select data from werte where idnr = ?', param1, function(err, rows1) {
      			if (err) throw new Error(err) 
      		}).then( (rows1) => {
      			console.log(param1+": "+rows1[0].data);
      			return connection.query('select data from werte where idnr = '+param2, function(err, rows2) {
      				if (err) throw new Error(err)
      			});
      		})
      		.then( (rows2) => {
      			console.log(param2+": "+rows2[0].data);
      			return connection.query('select data from werte where idnr = '+param3, function(err, rows3) {
      				if (err) throw new Error(err)
      			});
      		})
      		.then( (rows3) => {
      			console.log(param3+": "+rows3[0].data);
      			return connection.query('select data from werte where idnr = '+param4, function(err, rows4) {
      				if (err) throw new Error(err)
      			});
      		})
      		.then( (rows4) => {
      			console.log(param4+": "+rows4[0].data);
      		})
      	})
      
      

      Ich glaube, das funktioniert mit dem Promise dann nicht mehr, das mir ja mit dem "then" ermöglicht, Abfragen synchron nicht mehr asysnchron abzufragen und damit zuküntig das Ergebnis des ersten Query im zweiten zu verwenden.

      1. Tach!

        Die Fehlerbehandlung direkt in das Query einzubauen, wäre auch meine favorisierte Variante, ich weiß nur nicht recht, wie ich mit meinem Code verheirate.

        Am besten wird es, wenn du nicht die Vorgehensweisen mischst. Entweder gemäß Promise-mysql oder mysqljs.

        dedlfix.

        1. Ich hab nur halt bisher keine verschachtelten Promise-mysql-Pool Beispiele inklusive Fehlerbehandlung gefunden.

          1. Tach!

            Ich hab nur halt bisher keine verschachtelten Promise-mysql-Pool Beispiele inklusive Fehlerbehandlung gefunden.

            Das ist Standard-Fehlerbehandlung bei Promises. Ein Beispiel dazu ist auf der Seite zum Package, das vor der Überschrift "Pool".

            dedlfix.

            1. Das Beispiel da ist leider nicht mit verschachtelten Querys. Bei mir wird auch das "done(err)" vom Beispiel als nicht bekannt angemeckert.

              Ich habe es momentan so, allerdings wird bei einem Fehler nicht abgebrochen, sondern die 4. Abfrage wird trotzdem noch versucht, obwohl die Verbindung durch den Fehler bei 3 geschlossen wurde.

              mysqlPool.getConnection()
              	.then(connection => {
              		connection.query('select data from werte where idnr = ?', param1)
              		.catch(function(err) {
              			console.log("bei 0 Fehler aufgetreten");
              		})
              		.then( (rows1) => {
              			console.log(param1+": "+rows1[0].data);
              			return connection.query('select data from werte where idnr = '+param2);
              		})
              		.catch(function(err) {
              			console.log("bei 1 Fehler aufgetreten");
              		})
              		.then( (rows2) => {
              			console.log(param2+": "+rows2[0].data);
              			return connection.query('select data from werte where idnr = '+param3);
              		})
              		.catch(function(err) {
              			console.log("bei 2 Fehler aufgetreten");
              		})
              		.then( (rows3) => {
              			console.log(param3+": "+rows3[0].data);
              			return connection.query('select data from werte where idnr = '+param4);
              		})
              		.catch(function(err) {
              			console.log("bei 3 Fehler aufgetreten");
              			return;
              		})
              		.then( (rows4) => {
              			console.log(param4+": "+rows4[0].data);
              		})
              		.catch(function(err) {
              			console.log("bei 4 Fehler aufgetreten");
              		})
              	})
              
              
              

              Ausgabe:

              fertig 23: text 1 70: text 2 bei 3 Fehler aufgetreten bei 4 Fehler aufgetreten

              1. Tach!

                Das Beispiel da ist leider nicht mit verschachtelten Querys. Bei mir wird auch das "done(err)" vom Beispiel als nicht bekannt angemeckert.

                Das Beispiel vor dem Abschnitt Pool meinte ich, das hat kein done(). Da sind mehrere Abfragen im jeweils eigenen then() und ein catch() für die Fehler.

                Den Abschnitt Pool selbst solltest du gar nicht weiter beachten, oder willst du was mit Pools machen? Braucht man eigentlich nicht.

                dedlfix.

                1. Guten Morgen,

                  ich muss ehrlich gestehen, dass ich nicht so recht weiß, wofür die Nutzung von Pool gut ist. Mir hat wohl hauptsächlich der übersichtlichere Code gefallen und dass es auf Anhieb funktioniert hat. Das Beispiel über Pool von der von Dir genannten Seite, läuft bei mir gar nicht, sondern wirft direkt einen Fehler raus:

                  mysql.createConnection({
                  ^^^^^
                  SyntaxError: Unexpected identifier
                  

                  Selbst das Minimal-Beispiel nicht:

                  var mysql = require('promise-mysql');
                   
                  mysql.createConnection({
                      host: 'localhost',
                      user: 'sauron',
                      password: 'theonetruering',
                      database: 'mordor'
                  }).then(function(conn){
                      // do stuff with conn
                      conn.end();
                  });
                  
                  1. Tach!

                    Das Beispiel über Pool von der von Dir genannten Seite, läuft bei mir gar nicht, sondern wirft direkt einen Fehler raus:

                    mysql.createConnection({
                    ^^^^^
                    SyntaxError: Unexpected identifier
                    

                    Sieht aus, als ob im Code davor ein Syntaxfehler ist.

                    Selbst das Minimal-Beispiel nicht:

                    var mysql = require('promise-mysql');
                     
                    mysql.createConnection({
                        host: 'localhost',
                        user: 'sauron',
                        password: 'theonetruering',
                        database: 'mordor'
                    }).then(function(conn){
                        // do stuff with conn
                        conn.end();
                    });
                    

                    Definiere "läuft nicht". Das Beispiel macht ja auch nichts weiter als eine Verbindung auf- und wieder abzubauen. Solange es keine Fehlermeldung wirft, müsstest du noch irgendwas einbauen (eine Ausgabe beispielsweise), um nachzuvollziehen, ob bestimmte Teile des Codes abgearbeitet werden oder nicht.

                    dedlfix.

                    1. Du hattest recht, der Fehler lag davor. Schande über mich.

                      Ich hab es jetzt soweit hinbekommen, dass das Script jetzt genau das macht, was es soll und bei einem Fehler nicht das Script beendet.

                      Vielen Dank für Deine Unterstützung.

                      mysql.createConnection(mysqlConnData).then(function(conn){
                      	connection = conn;
                      	return connection.query('select data from werte where idnr = ?', param1);
                      }).then(function(rows){
                      	console.log("1. "+rows[0].data);
                      	var result = connection.query('select data from werte where idnr = ?', param2);
                      	return result;
                      }).then(function(rows){
                      	console.log("2. "+rows[0].data);
                      	var result = connection.query('select data from werte where idnr = ?', param3);
                      	return result;
                      }).then(function(rows){
                      	console.log("3. "+rows[0].data);
                      	var result = connection.query('select data from werte where idnr = ?', param4);
                      	connection.end();
                      	return result;
                      }).then(function(rows){
                      	console.log("4. "+rows[0].data);
                      	connection.end();
                      	return;
                      }).catch(function(error){
                      	if (connection && connection.end) connection.end();
                      	//logs out the error
                      	console.log(error);
                      });