Merge pull request #451 from CartoDB/errorLogs

Logging all errors
This commit is contained in:
Simon Martín 2017-12-13 15:08:19 +01:00 committed by GitHub
commit ee1cc28379
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 140 additions and 4 deletions

View File

@ -32,6 +32,8 @@ module.exports = function handleException(err, res) {
res.header('X-SQLAPI-Profiler', req.profiler.toJSONString());
}
setErrorHeader(msg, pgErrorHandler.getStatus(), res);
res.header('Content-Type', 'application/json; charset=utf-8');
res.status(getStatusError(pgErrorHandler, req));
if (req.query && req.query.callback) {
@ -56,3 +58,15 @@ function getStatusError(pgErrorHandler, req) {
return statusError;
}
function setErrorHeader(err, statusCode, res) {
let errorsLog = Object.assign({}, err);
errorsLog.statusCode = statusCode || 200;
errorsLog.message = errorsLog.error[0];
// remove double quotes for logs
errorsLog.message = errorsLog.message.replace(/"/g, "");
delete errorsLog.error;
res.set('X-SQLAPI-Errors', JSON.stringify(errorsLog));
}

View File

@ -8,7 +8,7 @@ module.exports.base_url = '(?:/api/:version|/user/:user/api/:version)';
// X-SQLAPI-Profile header containing elapsed timing for various
// steps taken for producing the response.
module.exports.useProfiler = true;
module.exports.log_format = '[:date] :remote-addr :method :req[Host]:url :status :response-time ms -> :res[Content-Type] (:res[X-SQLAPI-Profiler])';
module.exports.log_format = '[:date] :remote-addr :method :req[Host]:url :status :response-time ms -> :res[Content-Type] (:res[X-SQLAPI-Profiler]) (:res[X-SQLAPI-Errors])';
// If log_filename is given logs will be written there, in append mode. Otherwise stdout is used (default).
// Log file will be re-opened on receiving the HUP signal
module.exports.log_filename = 'logs/cartodb-sql-api.log';

View File

@ -8,7 +8,7 @@ module.exports.base_url = '(?:/api/:version|/user/:user/api/:version)';
// X-SQLAPI-Profile header containing elapsed timing for various
// steps taken for producing the response.
module.exports.useProfiler = true;
module.exports.log_format = '[:date] :remote-addr :method :req[Host]:url :status :response-time ms -> :res[Content-Type] (:res[X-SQLAPI-Profiler])';
module.exports.log_format = '[:date] :remote-addr :method :req[Host]:url :status :response-time ms -> :res[Content-Type] (:res[X-SQLAPI-Profiler]) (:res[X-SQLAPI-Errors])';
// If log_filename is given logs will be written there, in append mode. Otherwise stdout is used (default).
// Log file will be re-opened on receiving the HUP signal
module.exports.log_filename = 'logs/cartodb-sql-api.log';

View File

@ -8,7 +8,7 @@ module.exports.base_url = '(?:/api/:version|/user/:user/api/:version)';
// X-SQLAPI-Profile header containing elapsed timing for various
// steps taken for producing the response.
module.exports.useProfiler = true;
module.exports.log_format = '[:date] :req[X-Real-IP] :method :req[Host]:url :status :response-time ms -> :res[Content-Type] (:res[X-SQLAPI-Profiler])';
module.exports.log_format = '[:date] :req[X-Real-IP] :method :req[Host]:url :status :response-time ms -> :res[Content-Type] (:res[X-SQLAPI-Profiler]) (:res[X-SQLAPI-Errors])';
// If log_filename is given logs will be written there, in append mode. Otherwise stdout is used (default).
// Log file will be re-opened on receiving the HUP signal
module.exports.log_filename = 'logs/cartodb-sql-api.log';

View File

@ -8,7 +8,7 @@ module.exports.base_url = '(?:/api/:version|/user/:user/api/:version)';
// X-SQLAPI-Profile header containing elapsed timing for various
// steps taken for producing the response.
module.exports.useProfiler = true;
module.exports.log_format = '[:date] :remote-addr :method :req[Host]:url :status :response-time ms -> :res[Content-Type] (:res[X-SQLAPI-Profiler])';
module.exports.log_format = '[:date] :remote-addr :method :req[Host]:url :status :response-time ms -> :res[Content-Type] (:res[X-SQLAPI-Profiler]) (:res[X-SQLAPI-Errors])';
// If log_filename is given logs will be written there, in append mode. Otherwise stdout is used (default).
// Log file will be re-opened on receiving the HUP signal
// module.exports.log_filename = 'logs/cartodb-sql-api.log';

View File

@ -0,0 +1,31 @@
var server = require('../../app/server')();
var assert = require('../support/assert');
describe('error handler', function () {
it('should returns a errors header', function (done) {
const errorHeader = {
detail: undefined,
hint: undefined,
context: undefined,
statusCode: 400,
message: 'You must indicate a sql query'
};
assert.response(server, {
url: '/api/v1/sql',
headers: {host: 'vizzuality.cartodb.com'},
method: 'GET'
},
{
status: 400,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-SQLAPI-Errors': JSON.stringify(errorHeader)
}
},
function(err){
assert.ifError(err);
done();
});
});
});

View File

@ -0,0 +1,91 @@
'use strict';
var assert = require('assert');
var errorHandler = require('../../app/utils/error_handler');
describe('error-handler', function() {
it('should return a header with errors', function (done) {
const error = new Error('error test');
error.detail = 'test detail';
error.hint = 'test hint';
error.context = 'test context';
const res = {
req: {},
headers: {},
set (key, value) {
this.headers[key] = value;
},
header (key, value) {
this.set(key, value);
},
statusCode: 0,
status (status) {
this.statusCode = status;
},
json () {}
};
const errorHeader = {
detail: error.detail,
hint: error.hint,
context: error.context,
statusCode: 400,
message: error.message
};
errorHandler(error, res);
assert.ok(res.headers['X-SQLAPI-Errors'].length > 0);
assert.deepEqual(
res.headers['X-SQLAPI-Errors'],
JSON.stringify(errorHeader)
);
done();
});
it('JSONP should return a header with error statuscode', function (done) {
const error = new Error('error test');
error.detail = 'test detail';
error.hint = 'test hint';
error.context = 'test context';
const res = {
req: {
query: { callback: true }
},
headers: {},
set (key, value) {
this.headers[key] = value;
},
header (key, value) {
this.set(key, value);
},
statusCode: 0,
status (status) {
this.statusCode = status;
},
jsonp () {}
};
const errorHeader = {
detail: error.detail,
hint: error.hint,
context: error.context,
statusCode: 400,
message: error.message
};
errorHandler(error, res);
assert.ok(res.headers['X-SQLAPI-Errors'].length > 0);
assert.deepEqual(
res.headers['X-SQLAPI-Errors'],
JSON.stringify(errorHeader)
);
done();
});
});