diff --git a/src/controllers/docsControllers.js b/src/controllers/docsControllers.js index 19c7ac3..51578f0 100644 --- a/src/controllers/docsControllers.js +++ b/src/controllers/docsControllers.js @@ -60,13 +60,16 @@ docPath: "/docs", docModule: null, }); - - res.render("docs/index", { - ...context, - docsPaths: yamlFiles.map((name) => `${req.baseUrl || ""}/${name}`), - }); + try { + res.render("docs/index", { + ...context, + docsPaths: yamlFiles.map((name) => `${req.baseUrl || ""}/${name}`), + }); + } catch (err) { + return next(new HttpError("Failed to render page", 424, err.stack)); + } } catch (err) { - next(new HttpError("Failed to read docs directory", 500, err.stack)); + return next(new HttpError("Failed to read docs directory", 500, err.stack)); } }; @@ -90,13 +93,16 @@ docPath: baseUrl + "/docs/summary", docModule: null, }); - - res.render("docs/summary", { - ...context, - summaries, - }); + try { + res.render("docs/summary", { + ...context, + summaries, + }); + } catch (err) { + return next("Failed to render page", 424, err.stack); + } } catch (err) { - next(err); + return next(err); } }; @@ -118,14 +124,17 @@ name: key, url: `${baseUrl}/docs/${docPath}/${key}`, })); - - res.render("docs/path", { - ...context, - docsHome: qualifyLink("/docs"), - pathName: docPath, - crossCuttingSummary: doc.crossCuttingSummary, - modules: modulesWithLinks, - }); + try { + res.render("docs/path", { + ...context, + docsHome: qualifyLink("/docs"), + pathName: docPath, + crossCuttingSummary: doc.crossCuttingSummary, + modules: modulesWithLinks, + }); + } catch (e) { + return next(new HttpError("Failed to render page", 424, err.stack)); + } }; exports.renderDocsModule = async (req, res, next) => { @@ -147,12 +156,16 @@ docModule: module, }); - res.render("docs/module", { - ...context, - docsHome: qualifyLink("/docs"), - pathUrl: qualifyLink("/docs/" + docPath), - pathName: docPath, - module, - moduleDoc: filterModuleSecurityKeys(moduleDoc), - }); + try { + res.render("docs/module", { + ...context, + docsHome: qualifyLink("/docs"), + pathUrl: qualifyLink("/docs/" + docPath), + pathName: docPath, + module, + moduleDoc: filterModuleSecurityKeys(moduleDoc), + }); + } catch (err) { + return next(new HttpError("Failed to render page", 424, err.stack)); + } }; diff --git a/src/middleware/errorHandler.js b/src/middleware/errorHandler.js index b72ac93..eb6e663 100644 --- a/src/middleware/errorHandler.js +++ b/src/middleware/errorHandler.js @@ -76,5 +76,10 @@ context ); res.status(errorContext.statusCode); - res.renderGenericMessage(errorPageContext); + try { + res.renderGenericMessage(errorPageContext); + } catch (e) { + winstonLogger.error(e, { context }); + res.send("Critical error."); + } }; diff --git a/src/middleware/hbs.js b/src/middleware/hbs.js index 6b20cfa..140fce4 100644 --- a/src/middleware/hbs.js +++ b/src/middleware/hbs.js @@ -49,6 +49,25 @@ json(context) { return JSON.stringify(context, null, 2); }, + // helperMissing(context, options) { + // var options = arguments[arguments.length - 1]; + // var args = Array.prototype.slice.call( + // arguments, + // 0, + // arguments.length - 1 + // ); + // return new Handlebars.SafeString( + // "Missing: " + options.name + "(" + args + ")" + // ); + // }, + // blockHelperMissing(context, options) { + // return ( + // "Helper '" + + // options.name + + // "' not found. Printing block: " + + // options.fn(context) + // ); + // }, // renderObject, }, extname: EXTENSION, diff --git a/src/utils/HttpError.js b/src/utils/HttpError.js index b2de2f5..0727cff 100644 --- a/src/utils/HttpError.js +++ b/src/utils/HttpError.js @@ -7,4 +7,5 @@ Error.captureStackTrace(this, this.constructor); } } + module.exports = HttpError; diff --git a/src/utils/RenderError.js b/src/utils/RenderError.js new file mode 100644 index 0000000..a78c165 --- /dev/null +++ b/src/utils/RenderError.js @@ -0,0 +1,12 @@ +const HttpError = require("./HttpError"); + +class RenderError extends HttpError { + constructor(message, statusCode = 500, metadata = {}) { + super(message); + this.name = "HttpError"; + this.statusCode = statusCode; + Object.assign(this, { metadata }); + Error.captureStackTrace(this, this.constructor); + } +} +module.exports = RenderError; diff --git a/src/utils/docsContext.js b/src/utils/docsContext.js index e61c095..a7b7656 100644 --- a/src/utils/docsContext.js +++ b/src/utils/docsContext.js @@ -46,8 +46,6 @@ const allYamlDocs = await loadAllYamlDocs(); const currentPath = overrides.docPath || null; - console.debug(`overrides: ${JSON.stringify(overrides)}`); - console.debug(`current Path: ${currentPath}`); const currentModule = overrides.docModule || null; const docsMenu = generateDocsMenuModel( allYamlDocs, diff --git a/src/utils/errorContext.js b/src/utils/errorContext.js index cbf296a..45c23b4 100644 --- a/src/utils/errorContext.js +++ b/src/utils/errorContext.js @@ -13,6 +13,10 @@ title: "Server Error", message: "An unexpected error occurred. Please try again later.", }, + 424: { + title: "Server Error", + message: "An unexpected error occurred. Please try again later.", + }, }; const nameMap = {