xml support added
This commit is contained in:
parent
13ec01fb18
commit
06c53d1f73
|
@ -8,6 +8,7 @@ var accepts = require('accepts');
|
||||||
var debug = require('debug')('strong-error-handler:http-response');
|
var debug = require('debug')('strong-error-handler:http-response');
|
||||||
var sendJson = require('./send-json');
|
var sendJson = require('./send-json');
|
||||||
var sendHtml = require('./send-html');
|
var sendHtml = require('./send-html');
|
||||||
|
var sendXml = require('./send-xml');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
|
||||||
module.exports = negotiateContentProducer;
|
module.exports = negotiateContentProducer;
|
||||||
|
@ -24,6 +25,7 @@ function negotiateContentProducer(req, options) {
|
||||||
var SUPPORTED_TYPES = [
|
var SUPPORTED_TYPES = [
|
||||||
'application/json', 'json',
|
'application/json', 'json',
|
||||||
'text/html', 'html',
|
'text/html', 'html',
|
||||||
|
'text/xml', 'xml',
|
||||||
];
|
];
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
@ -82,5 +84,8 @@ function resolveOperation(contentType) {
|
||||||
case 'text/html':
|
case 'text/html':
|
||||||
case 'html':
|
case 'html':
|
||||||
return sendHtml;
|
return sendHtml;
|
||||||
|
case 'text/xml':
|
||||||
|
case 'xml':
|
||||||
|
return sendXml;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright IBM Corp. 2016. All Rights Reserved.
|
||||||
|
// Node module: strong-error-handler
|
||||||
|
// This file is licensed under the MIT License.
|
||||||
|
// License text available at https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var js2xmlparser = require('js2xmlparser');
|
||||||
|
|
||||||
|
module.exports = function sendXml(res, data) {
|
||||||
|
var content = js2xmlparser.parse('error', data);
|
||||||
|
res.setHeader('Content-Type', 'text/xml; charset=utf-8');
|
||||||
|
res.end(content, 'utf-8');
|
||||||
|
};
|
|
@ -18,6 +18,7 @@
|
||||||
"debug": "^2.2.0",
|
"debug": "^2.2.0",
|
||||||
"ejs": "^2.4.2",
|
"ejs": "^2.4.2",
|
||||||
"http-status": "^0.2.2",
|
"http-status": "^0.2.2",
|
||||||
|
"js2xmlparser": "^2.0.2",
|
||||||
"strong-globalize": "^2.6.7"
|
"strong-globalize": "^2.6.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -435,6 +435,81 @@ describe('strong-error-handler', function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
context('XML response', function() {
|
||||||
|
it('contains all error properties when debug=true', function(done) {
|
||||||
|
var error = new ErrorWithProps({
|
||||||
|
message: 'a test error message',
|
||||||
|
details: 'some details',
|
||||||
|
extra: 'sensitive data',
|
||||||
|
});
|
||||||
|
error.statusCode = 500;
|
||||||
|
givenErrorHandlerForError(error, {debug: true});
|
||||||
|
requestXML()
|
||||||
|
.expect(500)
|
||||||
|
.expect(/<statusCode>500<\/statusCode>/)
|
||||||
|
.expect(/<name>ErrorWithProps<\/name>/)
|
||||||
|
.expect(/<message>a test error message<\/message>/)
|
||||||
|
.expect(/<details>some details<\/details>/)
|
||||||
|
.expect(/<extra>sensitive data<\/extra>/)
|
||||||
|
.expect(/<stack>ErrorWithProps: a test error message(.*?)/, done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('contains subset of properties when status=4xx', function(done) {
|
||||||
|
var error = new ErrorWithProps({
|
||||||
|
name: 'ValidationError',
|
||||||
|
message: 'The model instance is not valid.',
|
||||||
|
statusCode: 422,
|
||||||
|
details: 'some details',
|
||||||
|
extra: 'sensitive data',
|
||||||
|
});
|
||||||
|
givenErrorHandlerForError(error, {debug: false});
|
||||||
|
requestXML()
|
||||||
|
.end(function(err, res) {
|
||||||
|
expect(res.statusCode).to.eql(422);
|
||||||
|
var body = res.error.text;
|
||||||
|
expect(body).to.match(/<details>some details<\/details>/);
|
||||||
|
expect(body).to.not.match(/<extra>sensitive data<\/extra>/);
|
||||||
|
expect(body).to.match(/<name>ValidationError<\/name>/);
|
||||||
|
expect(body).to.match(
|
||||||
|
/<message>The model instance is not valid.<\/message>/
|
||||||
|
);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('contains only safe info when status=5xx', function(done) {
|
||||||
|
// Mock an error reported by fs.readFile
|
||||||
|
var error = new ErrorWithProps({
|
||||||
|
name: 'Error',
|
||||||
|
message: 'ENOENT: no such file or directory, open "/etc/passwd"',
|
||||||
|
errno: -2,
|
||||||
|
code: 'ENOENT',
|
||||||
|
syscall: 'open',
|
||||||
|
path: '/etc/password',
|
||||||
|
});
|
||||||
|
givenErrorHandlerForError(error);
|
||||||
|
|
||||||
|
requestXML()
|
||||||
|
.end(function(err, res) {
|
||||||
|
expect(res.statusCode).to.eql(500);
|
||||||
|
var body = res.error.text;
|
||||||
|
expect(body).to.not.match(/\/etc\/password/);
|
||||||
|
expect(body).to.not.match(/-2/);
|
||||||
|
expect(body).to.not.match(/ENOENT/);
|
||||||
|
// only have the following
|
||||||
|
expect(body).to.match(/<statusCode>500<\/statusCode>/);
|
||||||
|
expect(body).to.match(/<message>Internal Server Error<\/message>/);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function requestXML(url) {
|
||||||
|
return request.get(url || '/')
|
||||||
|
.set('Accept', 'text/xml')
|
||||||
|
.expect('Content-Type', /^text\/xml/);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
context('Content Negotiation', function() {
|
context('Content Negotiation', function() {
|
||||||
it('defaults to json without options', function(done) {
|
it('defaults to json without options', function(done) {
|
||||||
givenErrorHandlerForError(new Error('Some error'), {});
|
givenErrorHandlerForError(new Error('Some error'), {});
|
||||||
|
|
Loading…
Reference in New Issue