Skip to content

Commit 6b55201

Browse files
committed
feat: honor "expose" property of http-errors
Signed-off-by: dhmlau <[email protected]> Signed-off-by: getsnoopy <[email protected]>
1 parent 5f6e31c commit 6b55201

File tree

3 files changed

+85
-5
lines changed

3 files changed

+85
-5
lines changed

lib/data-builder.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ function buildResponseData(err, options) {
3535
}
3636

3737
if (data.statusCode >= 400 && data.statusCode <= 499) {
38-
fillBadRequestError(data, err);
38+
fillClientError(data, err);
3939
} else {
40-
fillInternalError(data, err);
40+
fillServerError(data, err);
4141
}
4242

4343
const safeFields = options.safeFields || [];
@@ -66,15 +66,20 @@ function fillDebugData(data, err) {
6666
cloneAllProperties(data, err);
6767
}
6868

69-
function fillBadRequestError(data, err) {
69+
function fillClientError(data, err) {
7070
data.name = err.name;
7171
data.message = err.message;
7272
data.code = err.code;
7373
data.details = err.details;
7474
}
7575

76-
function fillInternalError(data, err) {
77-
data.message = httpStatus[data.statusCode] || 'Unknown Error';
76+
function fillServerError(data, err) {
77+
if (err.expose) {
78+
data.name = httpStatus[data.statusCode] || 'Unknown Error';
79+
data.message = err.message;
80+
} else {
81+
data.message = httpStatus[data.statusCode] || 'Unknown Error';
82+
}
7883
}
7984

8085
function fillSafeFields(data, err, safeFields) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"main": "lib/handler.js",
1414
"scripts": {
1515
"lint": "eslint .",
16+
"lint:fix": "eslint . --fix",
1617
"test": "mocha",
1718
"posttest": "npm run lint"
1819
},

test/handler.test.mjs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,33 @@ describe('strong-error-handler', function() {
392392
});
393393
});
394394

395+
it('honours expose=true when status=5xx', function(done) {
396+
// Mock an error reported by fs.readFile
397+
const error = new ErrorWithProps({
398+
name: 'Error',
399+
message: 'ENOENT: no such file or directory, open "/etc/passwd"',
400+
errno: -2,
401+
code: 'ENOENT',
402+
expose: true,
403+
syscall: 'open',
404+
path: '/etc/password',
405+
});
406+
givenErrorHandlerForError(error);
407+
408+
requestJson().end(function(err, res) {
409+
if (err) return done(err);
410+
411+
expect(res.body).to.have.property('error');
412+
expect(res.body.error).to.eql({
413+
statusCode: 500,
414+
name: 'Internal Server Error',
415+
message: 'ENOENT: no such file or directory, open "/etc/passwd"',
416+
});
417+
418+
done();
419+
});
420+
});
421+
395422
it('handles array argument as 500 when debug=false', function(done) {
396423
const errors = [new Error('ERR1'), new Error('ERR2'), 'ERR STRING'];
397424
givenErrorHandlerForError(errors);
@@ -702,6 +729,29 @@ describe('strong-error-handler', function() {
702729
});
703730
});
704731

732+
it('honours expose=true when status=5xx', function(done) {
733+
const error = new ErrorWithProps({
734+
name: 'Error',
735+
message: 'Server out of disk space',
736+
details: 'some details',
737+
extra: 'sensitive data',
738+
expose: true,
739+
});
740+
givenErrorHandlerForError(error);
741+
742+
requestHTML()
743+
.end(function(err, res) {
744+
expect(res.statusCode).to.eql(500);
745+
const body = res.error.text;
746+
expect(body).to.not.match(/some details/);
747+
expect(body).to.not.match(/sensitive data/);
748+
// only have the following
749+
expect(body).to.match(/<title>Internal Server Error<\/title>/);
750+
expect(body).to.match(/500(.*?)Server out of disk space/);
751+
done();
752+
});
753+
});
754+
705755
function requestHTML(url) {
706756
return request.get(url || '/')
707757
.set('Accept', 'text/html')
@@ -777,6 +827,30 @@ describe('strong-error-handler', function() {
777827
});
778828
});
779829

830+
it('honours expose=true when status=5xx', function(done) {
831+
const error = new ErrorWithProps({
832+
name: 'Error',
833+
message: 'Server out of disk space',
834+
details: 'some details',
835+
extra: 'sensitive data',
836+
expose: true,
837+
});
838+
givenErrorHandlerForError(error);
839+
840+
requestXML()
841+
.end(function(err, res) {
842+
expect(res.statusCode).to.eql(500);
843+
const body = res.error.text;
844+
expect(body).to.not.match(/some details/);
845+
expect(body).to.not.match(/sensitive data/);
846+
// only have the following
847+
expect(body).to.match(/<statusCode>500<\/statusCode>/);
848+
expect(body).to.match(/<name>Internal Server Error<\/name>/);
849+
expect(body).to.match(/<message>Server out of disk space<\/message>/);
850+
done();
851+
});
852+
});
853+
780854
it('honors options.rootProperty', function(done) {
781855
const error = new ErrorWithProps({
782856
name: 'ValidationError',

0 commit comments

Comments
 (0)