commit
ee1cc28379
@ -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));
|
||||
}
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
31
test/acceptance/error-handler.js
Normal file
31
test/acceptance/error-handler.js
Normal 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();
|
||||
});
|
||||
});
|
||||
});
|
91
test/unit/error_handler.test.js
Normal file
91
test/unit/error_handler.test.js
Normal 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();
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in New Issue
Block a user