diff --git a/lib/postgresql_interface.js b/lib/postgresql_interface.js index 9853b4c1..2e21338e 100644 --- a/lib/postgresql_interface.js +++ b/lib/postgresql_interface.js @@ -21,10 +21,13 @@ function isUniqueViolation(err) { return err.code === '23505'; } +function isLowSeverity(err) { + return isUniqueViolation(err) || err.severity === 'low'; +} + var conString = null; function rollback(client, done) { - logger.warn('Rolling back transaction.'); client.query('ROLLBACK', function(err) { return done(err); }); @@ -89,9 +92,10 @@ exports.recordBill = function recordBill(session, rec, cb) { if (cerr) return cb(cerr); query(client, getInsertQuery('bills', fields, false), values, function(err) { done(); - // TODO: Handle unique violations more cleanly for idempotency - // Now, it just returns an error, which should be fine, but a 204 status - // would be nicer. + if (err && isUniqueViolation(err)) { + logger.warn('Attempt to report bill twice'); + return cb(); + } cb(err); }); }); @@ -116,8 +120,10 @@ function query(client, queryStr, values, cb) { client.query(queryStr, values, function(err, results) { if (err) { - console.log(queryStr); - console.log(values); + if (!isLowSeverity(err)) { + console.log(queryStr); + console.log(values); + } return cb(err); } cb(null, results); @@ -132,8 +138,10 @@ function silentQuery(client, queryStr, values, cb) { client.query(queryStr, values, function(err) { if (err) { - console.log(queryStr); - console.log(values); + if (!isLowSeverity(err)) { + console.log(queryStr); + console.log(values); + } cb(err); } cb(); @@ -328,7 +336,13 @@ function insertTx(client, session, incoming, tx, satoshis, fiat, stage, function refreshPendingTx(client, session, cb) { var sql = 'UPDATE pending_transactions SET updated=now() ' + 'WHERE device_fingerprint=$1 AND session_id=$2'; - query(client, sql, [session.fingerprint, session.id], cb); + connect(function(cerr, client, done) { + if (cerr) return cb(cerr); + query(client, sql, [session.fingerprint, session.id], function(err) { + done(err); + cb(err); + }); + }); } function addPendingTx(client, session, incoming, currencyCode, toAddress, @@ -339,12 +353,7 @@ function addPendingTx(client, session, incoming, currencyCode, toAddress, var values = [session.fingerprint, session.id, incoming, currencyCode, toAddress, satoshis]; query(client, sql, values, function(err) { - - if (err && isUniqueViolation(err)) { - return refreshPendingTx(client, session, cb); - } - if (err) return cb(err); - cb(); + cb(err); }); } @@ -441,6 +450,7 @@ function ensureNotFinal(client, session, cb) { if (results.rows.length > 0) { error = new Error('Final request already exists'); error.name = 'staleBill'; + error.severity = 'low'; return cb(error); } cb(); @@ -459,13 +469,20 @@ exports.addOutgoingPending = function addOutgoingPending(session, currencyCode, 0) ], function(err) { if (err) { - rollback(client, done); - if (err.name === 'staleBill') { - logger.info('Received a bill insert after send coins request'); - return cb(); - } - logger.error(err); - return cb(err); + return rollback(client, function(rberr) { + done(rberr); + + if (isUniqueViolation(err)) { + // Pending tx exists, refresh it. + return refreshPendingTx(client, session, cb); + } + if (err.name === 'staleBill') { + logger.info('Received a bill insert after send coins request'); + return cb(); + } + logger.error(err); + return cb(err); + }); } silentQuery(client, 'COMMIT', null, function() { done();