From ec4ab82edaba12fe0c3cf2094e5792cdd9f2e9f4 Mon Sep 17 00:00:00 2001 From: GDColon Date: Wed, 18 Aug 2021 20:10:35 -0400 Subject: [PATCH] Better server error handling RobTop finally got https lets goo --- api/comments.js | 2 +- api/download.js | 2 +- api/gauntlets.js | 2 +- api/icon.js | 4 ++-- api/leaderboards/leaderboardLevel.js | 2 +- api/leaderboards/scores.js | 2 +- api/level.js | 2 +- api/mappacks.js | 2 +- api/messages/countMessages.js | 2 +- api/messages/fetchMessage.js | 2 +- api/messages/getMessages.js | 2 +- api/post/like.js | 3 +-- api/post/postComment.js | 3 +-- api/post/postProfileComment.js | 5 ++--- api/profile.js | 2 +- api/search.js | 2 +- api/song.js | 2 +- assets/gauntlets/unknown.png | Bin 0 -> 27584 bytes index.js | 15 +++++++++++---- package.json | 2 +- 20 files changed, 31 insertions(+), 27 deletions(-) create mode 100644 assets/gauntlets/unknown.png diff --git a/api/comments.js b/api/comments.js index fa7efe7..d2be441 100644 --- a/api/comments.js +++ b/api/comments.js @@ -20,7 +20,7 @@ module.exports = async (app, req, res) => { req.gdRequest(path, req.gdParams(params), function(err, resp, body) { - if (err || body == '-1' || !body) return res.send("-1") + if (err) return res.send("-1") comments = body.split('|') comments = comments.map(x => x.split(':')) diff --git a/api/download.js b/api/download.js index 0bcc487..55fe092 100644 --- a/api/download.js +++ b/api/download.js @@ -21,7 +21,7 @@ module.exports = async (app, req, res, api, ID, analyze) => { req.gdRequest('downloadGJLevel22', { levelID }, function (err, resp, body) { - if (err || !body || body == '-1' || body.startsWith("<")) { + if (err) { if (analyze && api && req.server.downloadsDisabled) return res.send("-3") else if (!api && levelID < 0) return res.redirect(`/?daily=${levelID * -1}`) else return rejectLevel() diff --git a/api/gauntlets.js b/api/gauntlets.js index d4f7732..3e3b01a 100644 --- a/api/gauntlets.js +++ b/api/gauntlets.js @@ -10,7 +10,7 @@ module.exports = async (app, req, res) => { req.gdRequest('getGJGauntlets21', {}, function (err, resp, body) { - if (err || !body || body == '-1' || body.startsWith("<")) return res.send("-1") + if (err) return res.send("-1") let gauntlets = body.split('#')[0].split('|').map(x => app.parseResponse(x)).filter(x => x[3]) let gauntletList = gauntlets.map(x => ({ id: +x[1], name: gauntletNames[+x[1] - 1] || "Unknown", levels: x[3].split(",") })) diff --git a/api/icon.js b/api/icon.js index f9213d3..a426751 100644 --- a/api/icon.js +++ b/api/icon.js @@ -374,11 +374,11 @@ module.exports = async (app, req, res) => { // skip request by causing fake error lmao req.gdRequest(skipRequest ? "" : 'getGJUsers20', skipRequest ? {} : req.gdParams({ str: username, forceGD }, !forceGD), function (err1, res1, body1) { - let result = foundID ? foundID[0] : (accountMode || err1 || !body1 || body1 == "-1" || body1.startsWith("<")) ? username : app.parseResponse(body1)[16]; + let result = foundID ? foundID[0] : (accountMode || err1) ? username : app.parseResponse(body1)[16]; req.gdRequest('getGJUserInfo20', req.gdParams({ targetAccountID: result, forceGD }, !forceGD), function (err2, res2, body2) { - if (err2 || !body2 || body2 == '-1' || body2.startsWith("<")) return buildIcon(); + if (err2) return buildIcon(); let iconData = app.parseResponse(body2) if (!foundID && !forceGD) app.userCache(req.id, iconData[16], iconData[2], iconData[1]) return buildIcon(iconData, userCode); diff --git a/api/leaderboards/leaderboardLevel.js b/api/leaderboards/leaderboardLevel.js index eceb18b..bda8a8d 100644 --- a/api/leaderboards/leaderboardLevel.js +++ b/api/leaderboards/leaderboardLevel.js @@ -18,7 +18,7 @@ module.exports = async (app, req, res) => { req.gdRequest('getGJLevelScores211', params, function(err, resp, body) { - if (err || body == -1 || !body) return res.send({error: true, lastWorked: app.timeSince(req.id)}) + if (err) return res.send({error: true, lastWorked: app.timeSince(req.id)}) scores = body.split('|').map(x => app.parseResponse(x)).filter(x => x[1]) if (!scores.length) return res.send([]) else app.trackSuccess(req.id) diff --git a/api/leaderboards/scores.js b/api/leaderboards/scores.js index 0c59846..383e1e8 100644 --- a/api/leaderboards/scores.js +++ b/api/leaderboards/scores.js @@ -16,7 +16,7 @@ module.exports = async (app, req, res) => { req.gdRequest('getGJScores20', params, function(err, resp, body) { - if (err || body == '-1' || !body) return res.send("-1") + if (err) return res.send("-1") scores = body.split('|').map(x => app.parseResponse(x)).filter(x => x[1]) if (!scores.length) return res.send("-1") diff --git a/api/level.js b/api/level.js index 6a1aeaa..ad138a0 100644 --- a/api/level.js +++ b/api/level.js @@ -21,7 +21,7 @@ module.exports = async (app, req, res, api, analyze) => { req.gdRequest('getGJLevels21', { str: levelID, type: 0 }, function (err, resp, body) { - if (err || !body || body == '-1' || body.startsWith("<") || body.startsWith("##")) return rejectLevel() + if (err || body.startsWith("##")) return rejectLevel() let preRes = body.split('#')[0].split('|', 10) let author = body.split('#')[1].split('|')[0].split(':') diff --git a/api/mappacks.js b/api/mappacks.js index 6919885..7477b1c 100644 --- a/api/mappacks.js +++ b/api/mappacks.js @@ -13,7 +13,7 @@ module.exports = async (app, req, res) => { function mapPackLoop() { req.gdRequest('getGJMapPacks21', params, function (err, resp, body) { - if (err || !body || body == '-1' || body.startsWith("<")) return res.send("-1") + if (err) return res.send("-1") let newPacks = body.split('#')[0].split('|').map(x => app.parseResponse(x)).filter(x => x[2]) packs = packs.concat(newPacks) diff --git a/api/messages/countMessages.js b/api/messages/countMessages.js index 602a77b..e98ac53 100644 --- a/api/messages/countMessages.js +++ b/api/messages/countMessages.js @@ -11,7 +11,7 @@ module.exports = async (app, req, res) => { req.gdRequest('getGJUserInfo20', params, function (err, resp, body) { - if (err || body == -1 || body == -2 || !body) return res.status(400).send(`Error counting messages! Messages get blocked a lot so try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) + if (err) return res.status(400).send(`Error counting messages! Messages get blocked a lot so try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) else app.trackSuccess(req.id) let count = app.parseResponse(body)[38] if (!count) return res.status(400).send("Error fetching unread messages!") diff --git a/api/messages/fetchMessage.js b/api/messages/fetchMessage.js index b24bf16..b5ff38a 100644 --- a/api/messages/fetchMessage.js +++ b/api/messages/fetchMessage.js @@ -11,7 +11,7 @@ module.exports = async (app, req, res, api) => { req.gdRequest('downloadGJMessage20', params, function (err, resp, body) { - if (err || body == -1 || !body) return res.status(400).send(`Error fetching message! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) + if (err) return res.status(400).send(`Error fetching message! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) else app.trackSuccess(req.id) let x = app.parseResponse(body) diff --git a/api/messages/getMessages.js b/api/messages/getMessages.js index 055abd9..3a78a6e 100644 --- a/api/messages/getMessages.js +++ b/api/messages/getMessages.js @@ -13,7 +13,7 @@ module.exports = async (app, req, res, api) => { req.gdRequest('getGJMessages20', params, function (err, resp, body) { - if (err || body == -1 || body == -2 || !body) return res.status(400).send(`Error fetching messages! Messages get blocked a lot so try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) + if (err) return res.status(400).send(`Error fetching messages! Messages get blocked a lot so try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) else app.trackSuccess(req.id) let messages = body.split("|").map(msg => app.parseResponse(msg)) diff --git a/api/post/like.js b/api/post/like.js index 75e3131..a3b783d 100644 --- a/api/post/like.js +++ b/api/post/like.js @@ -30,8 +30,7 @@ module.exports = async (app, req, res) => { params.chk = chk req.gdRequest('likeGJItem211', params, function (err, resp, body) { - if (err) return res.status(400).send("The Geometry Dash servers returned an error! Perhaps they're down for maintenance") - if (!body || body == -1) return res.status(400).send(`The Geometry Dash servers rejected your vote! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) + if (err) return res.status(400).send(`The Geometry Dash servers rejected your vote! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) else app.trackSuccess(req.id) res.status(200).send((params.like == 1 ? 'Successfully liked!' : 'Successfully disliked!') + " (this will only take effect if this is your first time doing so)") }) diff --git a/api/post/postComment.js b/api/post/postComment.js index 863177e..f617ef5 100644 --- a/api/post/postComment.js +++ b/api/post/postComment.js @@ -38,8 +38,7 @@ module.exports = async (app, req, res) => { params.chk = chk req.gdRequest('uploadGJComment21', params, function (err, resp, body) { - if (err) return res.status(400).send("The Geometry Dash servers returned an error! Perhaps they're down for maintenance") - if (!body || body == -1) return res.status(400).send(`The Geometry Dash servers rejected your comment! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) + if (err) return res.status(400).send(`The Geometry Dash servers rejected your comment! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) if (body.startsWith("temp")) { let banStuff = body.split("_") return res.status(400).send(`You have been banned from commenting for ${(parseInt(banStuff[1]) / 86400).toFixed(0)} days. Reason: ${banStuff[2] || "None"}`) diff --git a/api/post/postProfileComment.js b/api/post/postProfileComment.js index 6acdbf1..a2a8d2b 100644 --- a/api/post/postProfileComment.js +++ b/api/post/postProfileComment.js @@ -23,9 +23,8 @@ module.exports = async (app, req, res) => { params.chk = chk req.gdRequest('uploadGJAccComment20', params, function (err, resp, body) { - if (err) return res.status(400).send("The Geometry Dash servers returned an error! Perhaps they're down for maintenance") - else if (!body || body == -1) return res.status(400).send(`The Geometry Dash servers rejected your profile post! Try again later, or make sure your username and password are entered correctly. Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) - if (body.startsWith("temp")) { + if (err) return res.status(400).send(`The Geometry Dash servers rejected your profile post! Try again later, or make sure your username and password are entered correctly. Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`) + else if (body.startsWith("temp")) { let banStuff = body.split("_") return res.status(400).send(`You have been banned from commenting for ${(parseInt(banStuff[1]) / 86400).toFixed(0)} days. Reason: ${banStuff[2] || "None"}`) } diff --git a/api/profile.js b/api/profile.js index 2d4d76c..55e0589 100644 --- a/api/profile.js +++ b/api/profile.js @@ -40,7 +40,7 @@ module.exports = async (app, req, res, api, getLevels) => { let account = app.parseResponse(body || "") let dumbGDPSError = req.isGDPS && (!account[16] || account[1].toLowerCase() == "undefined") - if (err2 || body == '-1' || !body || dumbGDPSError) { + if (err2 || dumbGDPSError) { if (!api) return res.redirect('/search/' + req.params.id) else return res.send("-1") } diff --git a/api/search.js b/api/search.js index 7591ac4..74591cc 100644 --- a/api/search.js +++ b/api/search.js @@ -95,7 +95,7 @@ module.exports = async (app, req, res) => { req.gdRequest('getGJLevels21', req.gdParams(filters), function(err, resp, body) { - if (err || !body || body == '-1' || body.startsWith("<")) return res.send("-1") + if (err) return res.send("-1") let splitBody = body.split('#') let preRes = splitBody[0].split('|') let authorList = {} diff --git a/api/song.js b/api/song.js index a2b7348..0dc6573 100644 --- a/api/song.js +++ b/api/song.js @@ -8,7 +8,7 @@ module.exports = async (app, req, res) => { let songID = req.params.song req.gdRequest('getGJSongInfo', {songID: songID}, function(err, resp, body) { - if (err || !body || body.startsWith("<")) return res.send('-1') + if (err) return res.send('-1') else if (body < 0) return res.send(false) request.get('https://www.newgrounds.com/audio/listen/' + songID, function(err2, resp2, song) { console.log(resp2.statusCode) diff --git a/assets/gauntlets/unknown.png b/assets/gauntlets/unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..260e09e9883d7c190bcbdac100a5a7689e2ac164 GIT binary patch literal 27584 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

{D8cfGsL@ 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 Nk2UrGt9)b^`G2o-$zT8g literal 0 HcmV?d00001 diff --git a/index.js b/index.js index 8bef0f5..40d6f10 100644 --- a/index.js +++ b/index.js @@ -105,7 +105,11 @@ app.use(async function(req, res, next) { let endpoint = req.endpoint if (params.forceGD || (params.form && params.form.forceGD)) endpoint = "http://boomlings.com/database/" request.post(endpoint + target + '.php', parameters, function(err, res, body) { - return cb(err, res, body) + let error = err + if (!error && (err || !body || body.match(/^-\d$/) || body.startsWith("error") || body.startsWith("<"))) { + error = {serverError: true, response: body} + } + return cb(error, res, body) }) } @@ -150,7 +154,7 @@ try { app.id = secrets.id app.gjp = secrets.gjp || app.xor.encrypt(secrets.password) app.sheetsKey = secrets.sheetsKey - if (!Number(app.id) || !secrets.password || !secrets.gjp || (secrets.password || secrets.gjp).includes("delete this line")) console.warn("Warning: No account ID and/or password has been provided in secretStuff.json! These are required for level leaderboards to work.") + if (!Number(app.id) || (!secrets.password && !secrets.gjp) || (secrets.password || secrets.gjp).includes("delete this line")) console.warn("Warning: No account ID and/or password has been provided in secretStuff.json! These are required for level leaderboards to work.") if (app.sheetsKey.includes("google sheets api key")) app.sheetsKey = undefined } @@ -161,11 +165,11 @@ catch(e) { else { console.warn("There was an error parsing your secretStuff.json file!"); console.error(e) } } -app.parseResponse = function (responseBody, splitter) { +app.parseResponse = function (responseBody, splitter=":") { if (!responseBody || responseBody == "-1") return {}; if (responseBody.startsWith("\nWarning:")) responseBody = responseBody.split("\n").slice(2).join("\n").trim() // GDPS'es are wild if (responseBody.startsWith("
")) responseBody = responseBody.split("
").slice(2).join("
").trim() // Seriously screw this - let response = responseBody.split('#')[0].split(splitter || ':'); + let response = responseBody.split('#')[0].split(splitter); let res = {}; for (let i = 0; i < response.length; i += 2) { res[response[i]] = response[i + 1]} @@ -324,4 +328,7 @@ app.use(function (err, req, res, next) { if (err && err.message == "Response timeout") res.status(500).send('Internal server error! (Timed out)') }) +process.on('uncaughtException', (e) => { console.log(e) }); +process.on('unhandledRejection', (e, p) => { console.log(e) }); + app.listen(app.config.port, () => console.log(`Site online! (port ${app.config.port})`)) \ No newline at end of file diff --git a/package.json b/package.json index d36ebb5..7b4d7af 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "license": "MIT", "private": true, "dependencies": { - "canvas": "^2.6.1", + "canvas": "^2.8.0", "compression": "^1.7.4", "connect-timeout": "^1.9.0", "express": "^4.17.1",