Step 1:
Create a Discord Channel in your Discord server.
Step 2:
Under Integrations, create a new Webhook that has the new channel in its settings. Download the Webhook URL.
Step 3:
Find your ExpressJS application error handler in app.js that looks like below:
const errorHandler = function(err, req, res ,next) {
// Error handler
}
Step 4:
Install the node-fetch package:
npm install node-fetch —save
Step 5:
Call Discord with your error and request details making a POST request with node-fetch, and filling in the content: field of an object, then converting it to JSON string. The content can only be text. Optionally you may create an ascii table using the ascii-table3 package. Check out the sample code below.
const errorDiscordData = function(err, req, res, next) {
let table = errorToTable(err, req, res, next);
let data = "\`\`\`" + table.toString() + "\`\`\`"
let domainPath = null;
domainPath = req.hostname;
if (process.env.NODE_ENV == "production") {
domainPath = "https://" + domainPath;
} else {
domainPath = "http://" + domainPath + ":8081";
}
if (req.path != "/")
domainPath += req.path;
// Discord doesn't visit the link when link posted in chat as wrapped in <>
// This helps, because without below fix, for every 404 error discord goes and triggers 3 others of the same.
domainPath = "<" + domainPath + ">"
return data + domainPath
}
const errorToTable = function(err, req, res, next) {
let username = req.user && req.user.firstname && req.user.lastname ? req.user.firstname + " " + req.user.lastname : null;
let userhandle = null;
// If name exists, use name + email, else just email, if no user use null.
if (req.user) {
if (username) {
userhandle = username + " " + req.user.email
} else {
userhandle = req.user.email
}
} else {
userhandle = null;
}
let table =
new asciitable.AsciiTable3()
.setHeading('app', 'user', 'method', 'error')
.setAlignCenter(3)
.addRowMatrix([
[req.thisApp ? req.thisApp.id : null,
userhandle,
req.method,
err.message
],
]);
// set compact style
table.setStyle('compact');
return table;
}
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
let headers = new fetch.Headers();
headers.set('Content-Type', 'application/json');
return fetch(discord_url, {
method: "post",
body: JSON.stringify({ content: errorDiscordData(err, req, res, next) }),
headers: headers
}).then(response => {
//console.log("Discord response:", result)
// Only share call stack in development
if (process.env.NODE_ENV == "development") {
// console.error(err);
}
// Handle passport login error:
if (handleSeparateAppLogin(err, req, res, next)) {
return;
}
// render the error page
res.status(err.status || 500);
res.render('default/marketing/error', { cache: directive, error: err });
})
});
Using this code, you can now post all your server errors to a Discord channel, analyze frequently occurring errors in real-time and fix them!