1

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 '[email protected]' 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)
5
  • can you show the complete error message? Commented Jul 5, 2020 at 20:40
  • @nbk definitely! I just updated the question Commented Jul 5, 2020 at 20:47
  • your field username is UNIQUE Or Primnary KEY and allows only one of a kind., you must catch the error and tell the user to enter another unsername/email or initiate the forgotten password routine Commented Jul 5, 2020 at 20:54
  • I understand but even when I wrapped it in a try-catch it still broke. Commented Jul 5, 2020 at 21:02
  • WHEN you get ER_DUP_ENTRY as error in your try catch the redirect to enter a new username(or what eve4r you want so it should be similiar to this stackoverflow.com/questions/49004109/… Commented Jul 5, 2020 at 21:22

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.