From 972d41037dce6a837dba82e7e9718b6f2710f4a4 Mon Sep 17 00:00:00 2001 From: KalleV Date: Tue, 22 Oct 2024 14:45:20 -0400 Subject: [PATCH] fix(html): avoid rendering [Object object] for undefined values Signed-off-by: KalleV --- lib/send-html.js | 16 +++++++++++++--- test/handler.test.mjs | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/send-html.js b/lib/send-html.js index 02b2adb..fe615b2 100644 --- a/lib/send-html.js +++ b/lib/send-html.js @@ -16,6 +16,8 @@ const compiledTemplates = { module.exports = sendHtml; +const STANDARD_PROPS = ['name', 'statusCode', 'message', 'stack']; + /** * Sends HTML response to the client. * @@ -24,7 +26,16 @@ module.exports = sendHtml; * @param {Object} options - The options object. */ function sendHtml(res, data, options) { - const toRender = {options, data}; + // Filter out properties with undefined / null values and keep standard properties + const filteredData = Object.keys(data).reduce((obj, key) => { + if (data[key] || STANDARD_PROPS.includes(key)) { + obj[key] = data[key]; + } + return obj; + }, {}); + + const toRender = {options, data: filteredData}; + // TODO: ability to call non-default template functions from options const body = compiledTemplates.default(toRender); sendResponse(res, body); @@ -50,8 +61,7 @@ handlebars.registerHelper('partial', partial); * @returns {string} - The result of the Handlebars template. */ function standardProps(prop, options) { - const standardProps = ['name', 'statusCode', 'message', 'stack']; - if (standardProps.indexOf(prop) === -1) { + if (STANDARD_PROPS.indexOf(prop) === -1) { return options.fn(this); } return options.inverse(this); diff --git a/test/handler.test.mjs b/test/handler.test.mjs index d1b04f7..dc52349 100644 --- a/test/handler.test.mjs +++ b/test/handler.test.mjs @@ -683,6 +683,27 @@ describe('strong-error-handler', function() { }); }); + it('hides undefined properties from the HTML response', function(done) { + const error = new ErrorWithProps({ + message: 'A test error message', + details: undefined, + code: undefined, + }); + error.statusCode = 400; + givenErrorHandlerForError(error); + requestHTML() + .end(function(err, res) { + expect(res.statusCode).to.eql(400); + + const body = res.error.text; + + expect(body).to.match(/400(.*?)A test error message/); + expect(body).not.to.match(/details/); + expect(body).not.to.match(/code/); + done(); + }); + }); + function requestHTML(url) { return request.get(url || '/') .set('Accept', 'text/html')