diff --git a/app.js b/app.js index 0d6f268..3101cdf 100755 --- a/app.js +++ b/app.js @@ -451,6 +451,8 @@ app.use(function(req, res, next) { res.locals.genesisBlockHash = coreApi.getGenesisBlockHash(); res.locals.genesisCoinbaseTransactionId = coreApi.getGenesisCoinbaseTransactionId(); + res.locals.pageErrors = []; + // currency format type if (!req.session.currencyFormatType) { diff --git a/routes/baseActionsRouter.js b/routes/baseActionsRouter.js index 2003c78..92721f1 100644 --- a/routes/baseActionsRouter.js +++ b/routes/baseActionsRouter.js @@ -613,13 +613,13 @@ router.get("/address/:address", function(req, res, next) { res.locals.addressObj = bitcoinjs.address.fromBase58Check(address); } catch (err) { - utils.logError("u3gr02gwef", err); + res.locals.pageErrors.push(utils.logError("u3gr02gwef", err)); try { res.locals.addressObj = bitcoinjs.address.fromBech32(address); } catch (err2) { - utils.logError("u02qg02yqge", err); + res.locals.pageErrors.push(utils.logError("u02qg02yqge", err)); } } @@ -714,7 +714,7 @@ router.get("/address/:address", function(req, res, next) { resolve2(); }).catch(function(err) { - utils.logError("78ewrgwetg3", err); + res.locals.pageErrors.push(utils.logError("78ewrgwetg3", err)); reject2(err); }); @@ -766,13 +766,13 @@ router.get("/address/:address", function(req, res, next) { resolve(); }).catch(function(err) { - utils.logError("230wefrhg0egt3", err); + res.locals.pageErrors.push(utils.logError("230wefrhg0egt3", err)); reject(err); }); }).catch(function(err) { - utils.logError("asdgf07uh23", err); + res.locals.pageErrors.push(utils.logError("asdgf07uh23", err)); reject(err); }); @@ -786,7 +786,7 @@ router.get("/address/:address", function(req, res, next) { resolve(); } }).catch(function(err) { - utils.logError("23t07ug2wghefud", err); + res.locals.pageErrors.push(utils.logError("23t07ug2wghefud", err)); res.locals.addressApiError = err; @@ -801,7 +801,7 @@ router.get("/address/:address", function(req, res, next) { resolve(); }).catch(function(err) { - utils.logError("132r80h32rh", err); + res.locals.pageErrors.push(utils.logError("132r80h32rh", err)); reject(err); }); @@ -811,7 +811,7 @@ router.get("/address/:address", function(req, res, next) { promises.push(new Promise(function(resolve, reject) { qrcode.toDataURL(address, function(err, url) { if (err) { - utils.logError("93ygfew0ygf2gf2", err); + res.locals.pageErrors.push(utils.logError("93ygfew0ygf2gf2", err)); } res.locals.addressQrCodeUrl = url; @@ -826,7 +826,7 @@ router.get("/address/:address", function(req, res, next) { next(); }).catch(function(err) { - utils.logError("32197rgh327g2", err); + res.locals.pageErrors.push(utils.logError("32197rgh327g2", err)); res.render("address"); @@ -834,7 +834,7 @@ router.get("/address/:address", function(req, res, next) { }); }).catch(function(err) { - utils.logError("2108hs0gsdfe", err, {address:address}); + res.locals.pageErrors.push(utils.logError("2108hs0gsdfe", err, {address:address})); res.locals.userMessage = "Failed to load address " + address + " (" + err + ")"; @@ -1003,7 +1003,7 @@ router.get("/rpc-browser", function(req, res, next) { debugLog("RPC Response: err=" + err3 + ", result=" + result3 + ", headers=" + resHeaders3); if (err3) { - utils.logError("23roewuhfdghe", err3, {method:req.query.method, params:argValues, result:result3, headers:resHeaders3}); + res.locals.pageErrors.push(utils.logError("23roewuhfdghe", err3, {method:req.query.method, params:argValues, result:result3, headers:resHeaders3})); if (result3) { res.locals.methodResult = {error:("" + err3), result:result3}; diff --git a/views/includes/page-errors-modal.pug b/views/includes/page-errors-modal.pug new file mode 100644 index 0000000..5460d6d --- /dev/null +++ b/views/includes/page-errors-modal.pug @@ -0,0 +1,34 @@ +div.modal.fade(id="pageErrorsModal" role="dialog" aria-hidden="true") + div.modal-dialog.modal-xl(role="document") + div.modal-content + div.modal-header + h5.modal-title Page Errors + + button.close(type="button" data-dismiss="modal" aria-label="Close") + span(aria-hidden="true") × + + div.modal-body + each item, itemIndex in pageErrors + div.card.shadow-sm(class=(itemIndex < (pageErrors.length - 1) ? "mb-3" : false)) + div.card-header + h6.mb-0 Error ##{(itemIndex + 1).toLocaleString()} + div.card-body + h6 Error Details + pre + code.json.bg-light #{JSON.stringify(item.error, null, 4)} + + if (item.error.stack) + hr + h6 Stacktrace + pre + code.json.bg-light #{item.error.stack} + + if (item.userData) + hr + + h4.h6 User Data + pre + code.json.bg-light #{JSON.stringify(error.userData, null, 4)} + + div.modal-footer + button.btn.btn-secondary(type="button" data-dismiss="modal") Close diff --git a/views/layout.pug b/views/layout.pug index a080efc..78d05e9 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -114,6 +114,14 @@ html(lang="en") div(class="pb-4 pt-3 pt-md-4", style=("background-color: " + bodyBgColor)) div(class="container px-2 px-sm-3") + if (pageErrors && pageErrors.length > 0) + include includes/page-errors-modal.pug + + div.float-right + div.alert.alert-danger.py-1.px-3.mb-n2.mt-n1.font-weight-bold(title=`This page encountered ${pageErrors.length.toLocaleString()} error(s). Click for details.` data-toggle="tooltip") + a.text-danger(href="javascript:void(0)" data-toggle="modal" data-target="#pageErrorsModal") Errors + span.badge.badge-danger.ml-2 #{pageErrors.length.toLocaleString()} + if (userMessage) div(class="alert", class=(userMessageType ? ("alert-" + userMessageType) : "alert-warning"), role="alert") span !{userMessage}