ensure DB errors are properly caught and internal errors are caught+logged but not shown in responses (fixes #259)

This commit is contained in:
Christopher Van 2014-12-17 16:33:38 -08:00
Родитель 6c9b63a4b0
Коммит 2484f86d31
4 изменённых файлов: 41 добавлений и 32 удалений

Просмотреть файл

@ -14,12 +14,12 @@ module.exports = {
'VALUES ($1, $2, $3, $4, NOW()) RETURNING *',
[game.slug, game.game_url, game.name, game.description],
function (err, result) {
if (err) {
return reject(err);
}
// TODO: Throw error if row couldn't be inserted.
resolve(err || result.rows[0]);
if (err) {
return reject(utils.errors.DatabaseError(err));
}
resolve(result.rows[0]);
});
});
},
@ -28,7 +28,7 @@ module.exports = {
get: function (request) {
return Game.objects.get(request.pg.client, {
idOrSlug: request.params.idOrSlug
}).catch(utils.returnError);
});
},
update: function () {
}

Просмотреть файл

@ -30,15 +30,14 @@ Game.objects.get = function (db, data) {
db.query(query, [data.idOrSlug], function (err, result) {
if (err) {
return reject(err);
return reject(utils.errors.DatabaseError(err));
}
if (!result.rows.length) {
return reject(utils.errors.DoesNotExist());
}
// TODO: Throw error when row couldn't get be selected (#259).
resolve(err || result.rows[0]);
resolve(result.rows[0]);
});
});
};

Просмотреть файл

@ -1,8 +1,7 @@
var hapi = require('hapi');
var joi = require('joi');
var gameController = require('./controllers/game.js');
var utils = require('../lib/utils');
module.exports = function (server) {
@ -10,11 +9,10 @@ module.exports = function (server) {
method: 'GET',
path: '/games',
handler: function (request, reply) {
gameController.get(request).then(reply, function (response) {
reply(response).code(response.statusCode);
}).catch(function (err) {
console.error(err);
reply(err);
gameController.get(request)
.then(reply)
.catch(function (err) {
reply(utils.returnError(err));
});
}
});
@ -23,11 +21,10 @@ module.exports = function (server) {
method: 'POST',
path: '/games',
handler: function (request, reply) {
gameController.create(request).then(reply, function (response) {
reply(response).code(response.statusCode);
}).catch(function (err) {
console.error(err);
reply(err);
gameController.create(request)
.then(reply)
.catch(function (err) {
reply(utils.returnError(err));
});
},
config: {
@ -59,7 +56,11 @@ module.exports = function (server) {
method: 'GET',
path: '/games/{idOrSlug}',
handler: function (request, reply) {
gameController.get(request).then(reply).catch(reply);
gameController.get(request)
.then(reply)
.catch(function (err) {
reply(utils.returnError(err));
});
},
// config: {
// validate: {

Просмотреть файл

@ -33,15 +33,24 @@ module.exports.promisify = function (func) {
module.exports.returnError = function (err) {
console.error('Caught error: %s', stringifyObject(err));
switch (err.name) {
case 'DatabaseError':
return Boom.badImplementation(err.message || 'database_error');
case 'DoesNotExist':
return Boom.notFound(err.message || 'does_not_exist');
case 'ValidationError':
return Boom.badRequest(err.message || 'validation_error');
default:
return Boom.badImplementation();
if (err instanceof Object) {
if (err instanceof Error) {
console.error('Caught stack:\n%s', err.stack);
} else if (err.name) {
console.error('Caught rejection:\n%s', stringifyObject(err));
switch (err.name) {
case 'DatabaseError':
// NOTE: The response will actually contain this generic message:
// "An internal server error occurred"
return Boom.badImplementation(err.message || 'database_error');
case 'DoesNotExist':
return Boom.notFound(err.message || 'does_not_exist');
case 'ValidationError':
return Boom.badRequest(err.message || 'validation_error');
}
}
}
return Boom.badImplementation(err);
};