简体   繁体   中英

How to handle a MySQL node query?

I'm trying to handle a dup key error when running a MySQL query in Node JS. I tried wrapping the call in a try-catch but there's still a crash. I also wrapped the create call in a try-catch but no luck. Does anyone how I can handle this crash?

create(first_name, last_name, username, email, password, callback) { 
    let salt = bcrypt.genSaltSync(SALT_ROUNDS);
    let hash = bcrypt.hashSync(password, salt);

    let sql = `INSERT INTO users (username, email, first_name, last_name, password) VALUES (?, ?, ?, ?, ?);`;
    let values = [
        username.toLowerCase(), email.toLowerCase(), 
        first_name.toLowerCase(), last_name.toLowerCase(), 
        hash
    ];

    // Crash below 
    try {
        db.query(sql, values, (error, results) => {
            if (error) {
                return callback(error, undefined);   
            }
            return callback(undefined, results.insertId)
        });
    } catch (error) {
        callback(error, undefined)
    }
}

NodeJs Route Call:

Users.create(first_name, last_name, username, email, password, (error, insertedId) => {
    if (error) {
        next(error);
    }
    ..
}

Error:

Database connected...
Error: ER_DUP_ENTRY: Duplicate entry 'test-test@gmail.com' for key 'username'
at Query.Sequence._packetToError (C:\Users\main\development\hvz-api\node_modules\mysql\lib\protocol\sequences\Sequence.js:47:14)
at Query.ErrorPacket (C:\Users\main\development\hvz-api\node_modules\mysql\lib\protocol\sequences\Query.js:79:18)
at Protocol._parsePacket (C:\Users\main\development\hvz-api\node_modules\mysql\lib\protocol\Protocol.js:291:23)
at Parser._parsePacket (C:\Users\main\development\hvz-api\node_modules\mysql\lib\protocol\Parser.js:433:10)
at Parser.write (C:\Users\main\development\hvz-api\node_modules\mysql\lib\protocol\Parser.js:43:10)
at Protocol.write (C:\Users\main\development\hvz-api\node_modules\mysql\lib\protocol\Protocol.js:38:16)
at Socket.<anonymous> (C:\Users\main\development\hvz-api\node_modules\mysql\lib\Connection.js:88:28)
at Socket.<anonymous> (C:\Users\main\development\hvz-api\node_modules\mysql\lib\Connection.js:526:10)
at Socket.emit (events.js:223:5)
at addChunk (_stream_readable.js:309:12)
..
..

C:\Users\main\development\hvz-api\node_modules\mysql\lib\protocol\Parser.js:437
      throw err; // Rethrow non-MySQL errors
      ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:485:11)
    at ServerResponse.header (C:\Users\main\development\hvz-api\node_modules\express\lib\response.js:767:10)
    at ServerResponse.send (C:\Users\main\development\hvz-api\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (C:\Users\main\development\hvz-api\node_modules\express\lib\response.js:267:15)

Since you already wrapped a try-catch around the relevant part of the code and there is still a crash, it is safe to assume that the crash happens inside the catch , that is, an exception is thrown from the try block, the catch block catches it and then something happens inside your catch block which raises another exception. You can try my theory via temporarily commenting out the code inside the catch just for the fun of it:

try {
    db.query(sql, values, (error, results) => {
        if (error) {
            return callback(error, undefined);   
        }
        return callback(undefined, results.insertId)
    });
} catch (error) {
    //callback(error, undefined)
}

If it does not throw an exception now, then your call to callback raises the error and you will need to change the code inside your catch so that it fails gracefully.

But this is only the technical solution. Conceptually you should not even run an insert which might be invalid. You should perform your validation checks and if everything is cool, then run the insert . You will still need a try-catch around it and a proper error handling to handle the changes which happen between your validation check and your insert though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM