diff options
| author | schneefux <schneefux+commit@schneefux.xyz> | 2017-05-09 13:24:41 +0200 |
|---|---|---|
| committer | schneefux <schneefux+commit@schneefux.xyz> | 2017-05-09 13:24:41 +0200 |
| commit | 54b59d1168e79c8706b164194bc1a48ec49726e4 (patch) | |
| tree | 82b685a4e934ba237db3abcdde51d6f8e2c1b993 | |
| parent | 31b4764cd5233acb25f4d0027261fe83eaad6ec7 (diff) | |
| download | discordbot-54b59d1168e79c8706b164194bc1a48ec49726e4.tar.gz discordbot-54b59d1168e79c8706b164194bc1a48ec49726e4.zip | |
error handling
| -rw-r--r-- | api.js | 56 | ||||
| -rw-r--r-- | commands/vainsocial/guild_add.js | 3 | ||||
| -rw-r--r-- | commands/vainsocial/guild_fame_calc.js | 36 | ||||
| -rw-r--r-- | commands/vainsocial/guild_update.js | 28 | ||||
| -rw-r--r-- | commands/vainsocial/match.js | 32 | ||||
| -rw-r--r-- | commands/vainsocial/matches.js | 22 | ||||
| -rw-r--r-- | commands/vainsocial/me.js | 16 | ||||
| -rw-r--r-- | commands/vainsocial/user.js | 23 | ||||
| -rw-r--r-- | util.js | 10 | ||||
| -rw-r--r-- | views/guild_add.js | 34 | ||||
| -rw-r--r-- | views/match.js | 11 | ||||
| -rw-r--r-- | views/register.js | 16 | ||||
| -rw-r--r-- | views/view.js | 10 |
13 files changed, 144 insertions, 153 deletions
@@ -43,19 +43,12 @@ module.exports.getMap = async (url) => { module.exports.getFE = module.exports.get = async (url, params={}, ttl=60, cachekey=undefined) => { if (cachekey == undefined) cachekey = url + JSON.stringify(params); - return await cache.wrap(cachekey, async () => { - try { - return await request({ - uri: API_FE_URL + url, - qs: params, - json: true, - forever: true - }); - } catch (err) { - // TODO sort errors, loggly - return undefined; - } - }, { ttl: ttl }); + return await cache.wrap(cachekey, async () => await request({ + uri: API_FE_URL + url, + qs: params, + json: true, + forever: true + }), { ttl: ttl }); } // send a POST and optionally bust cache @@ -139,7 +132,13 @@ module.exports.subscribeUpdates = (name, timeout=UPDATE_TIMEOUT) => { cache.del("matches+" + name); cache.del("player+" + name); } - if ([Channel.DONE, "search_fail"].indexOf(msg) != -1) { + if (msg == "search_fail") { + subscription.unsubscribe(); + throw { error: { + err: "No player found for the provided IGN." + } }; + } + if (msg == Channel.DONE) { subscription.unsubscribe(); return undefined; } @@ -156,14 +155,18 @@ module.exports.updatePlayer = (name) => api.postBE("/player/" + name + "/update"); // return player -module.exports.getPlayer = (name) => - api.getFE("/player/" + name, {}, 60, "player+" + name); +module.exports.getPlayer = async (name) => { + return await api.getFE("/player/" + name, {}, 60, "player+" + name); +} // search or update a player module.exports.upsearchPlayer = async (name) => { - if (await api.getPlayer(name) == undefined) + try { + await api.getPlayer(name); + await api.updatePlayer(name); + } catch (err) { await api.searchPlayer(name); - else await api.updatePlayer(name); + } } // block until update is completely done @@ -181,17 +184,18 @@ module.exports.upsearchPlayerSync = async (name) => { module.exports.getMatches = async (name) => { const data = await api.getFE("/player/" + name + "/matches/1.1.1.1", {}, 60 * 60, "matches+" + name); - if (data == undefined) return []; return data[0].data; } // return single match -module.exports.getMatch = async (id) => - await api.getFE("/match/" + id, {}, 60 * 60); +module.exports.getMatch = async (id) => { + return await api.getFE("/match/" + id, {}, 60 * 60); +} // return a guild -module.exports.getGuild = (token) => - api.getFE("/guild", { user_token: token }, 60, "guild+" + token); +module.exports.getGuild = async (token) => { + return await api.getFE("/guild", { user_token: token }, 60, "guild+" + token); +} // TODO! cache guilds by guild id, not by user token // add user to guild @@ -231,5 +235,7 @@ module.exports.setUser = async (token, name) => { } // retrieve Discord ID -> IGN -module.exports.getUser = async (token) => - (await api.getFE("/user", { user_token: token }, 60, "user+" + token)).name; +module.exports.getUser = async (token) => { + const user = await api.getFE("/user", { user_token: token }, 60, "user+" + token); + return user.name; +} diff --git a/commands/vainsocial/guild_add.js b/commands/vainsocial/guild_add.js index 0021360..8474724 100644 --- a/commands/vainsocial/guild_add.js +++ b/commands/vainsocial/guild_add.js @@ -7,7 +7,7 @@ const Commando = require("discord.js-commando"), Promise = require("bluebird"), api = require("../../api"), util = require("../../util"), - GuildAddView = require("../../views/guild_add"); + GuildAddView = require("../../views/guild_progress"); module.exports = class AddGuildMemberCommand extends Commando.Command { constructor(client) { @@ -24,7 +24,6 @@ Register IGNs to your Guild. argsType: "multiple" }); } - // register a VainSocial Guild to a Discord account async run(msg, args) { util.trackAction(msg, "vainsocial-guild-add"); let playersData = {}; diff --git a/commands/vainsocial/guild_fame_calc.js b/commands/vainsocial/guild_fame_calc.js deleted file mode 100644 index e1ec912..0000000 --- a/commands/vainsocial/guild_fame_calc.js +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/node -/* jshint esnext:true */ -"use strict"; - -const Commando = require("discord.js-commando"), - oneLine = require("common-tags").oneLine, - api = require("../../api"), - util = require("../../util"); - -module.exports = class CalculateGuildFameCommand extends Commando.Command { - constructor(client) { - super(client, { - name: "vainsocial-guildcalc", - aliases: ["vguild-calc", "vgcalc"], - group: "vainsocial-guild", - memberName: "vainsocial-guildcalc", - description: "Update your Guild's fame.", - details: oneLine` -Recalculate your Guild members' fame. -`, - examples: ["vgcalc"] - }); - } - // internal / premium: immediately call backend fame refresh - async run(msg, args) { - util.trackAction(msg, "vainsocial-guild-calculate"); - const guild = await api.getGuild(msg.author.id); - if (guild == undefined) { - await msg.reply("You are not registered in any guilds."); - return; - } - await msg.reply("Your Guild members' fame will be updated soon…"); - await api.calculateGuild(guild.id, msg.author.id); - await msg.reply("Your Guild members' fame has been updated."); - } -}; diff --git a/commands/vainsocial/guild_update.js b/commands/vainsocial/guild_update.js index 9c9fe1d..66e8a5f 100644 --- a/commands/vainsocial/guild_update.js +++ b/commands/vainsocial/guild_update.js @@ -6,7 +6,8 @@ const Commando = require("discord.js-commando"), oneLine = require("common-tags").oneLine, Promise = require("bluebird"), api = require("../../api"), - util = require("../../util"); + util = require("../../util"), + GuildMembersProgressView = require("../../views/guild_progress"); module.exports = class UpdateGuildCommand extends Commando.Command { constructor(client) { @@ -25,14 +26,21 @@ Update the match history for all your Guild members. // internal / premium: immediately call backend player refresh async run(msg, args) { util.trackAction(msg, "vainsocial-guild-update"); - const guild = await api.getGuild(msg.author.id); - if (guild == undefined) { - await msg.reply("You are not registered in any guilds."); - return; - } - // TODO progress report - await Promise.map(guild.members, - (member) => api.upsearchPlayer(member.player.name)); - await msg.reply("Your Guild members will be up to date soon."); + let playersData = {}; + const playersWaiters = args.map((name) => api.subscribeUpdates(name)), + guildUpdateView = new GuildMembersProgressView(msg, playersData); + // create waiter dict & data dict + await Promise.map(playersWaiters, async (waiter, idx) => { + await api.updatePlayer(args[idx]); + let success = false; + while (await waiter.next() != undefined) { + playersData[args[idx]] = await api.getPlayer(args[idx]); + await guildUpdateView.respond(); + success = true; + } + }); + await guildUpdateView.respond("Your Guild's fame is being updated…"); + await api.calculateGuild(guild.id, msg.author.id); + await guildUpdateView.respond("Your Guild was updated."); } }; diff --git a/commands/vainsocial/match.js b/commands/vainsocial/match.js index c3d2906..3acde84 100644 --- a/commands/vainsocial/match.js +++ b/commands/vainsocial/match.js @@ -42,19 +42,27 @@ module.exports = class ShowMatchCommand extends Commando.Command { } async run(msg, args) { util.trackAction(msg, "vainsocial-match", args.name); - const ign = await util.ignForUser(args.name, msg.author.id); - if (ign == undefined) return await msg.say(strings.unknown(msg)); + let ign; + try { + ign = await util.ignForUser(args.name, msg.author.id); + } catch (err) { + return await new MatchView(msg, undefined).error(strings.unknown(msg)); + } - const participations = await api.getMatches(ign); - if (args.number > participations.length) - return await msg.say(strings.tooFewMatches(ign)); - const matchView = new MatchView(msg, - participations[args.number-1].match_api_id); - // wait for BE update - const waiter = api.subscribeUpdates(ign); - await api.upsearchPlayer(ign); + const matchView = new MatchView(msg); + try { + const participations = await api.getMatches(ign); + if (args.number > participations.length) + return await msg.say(strings.tooFewMatches(ign)); + // wait for BE update + const waiter = api.subscribeUpdates(ign); + await api.upsearchPlayer(ign); - do await matchView.respond(); - while (await waiter.next() != undefined); + do await matchView.respond(participations[args.number-1].match_api_id); + while (await waiter.next() != undefined); + } catch (err) { + console.error(err); + return await matchView.error(err.error.err); + } } }; diff --git a/commands/vainsocial/matches.js b/commands/vainsocial/matches.js index 0197b8b..7499725 100644 --- a/commands/vainsocial/matches.js +++ b/commands/vainsocial/matches.js @@ -33,16 +33,24 @@ module.exports = class ShowMatchesCommand extends Commando.Command { } async run(msg, args) { util.trackAction(msg, "vainsocial-matches", args.name); - const ign = await util.ignForUser(args.name, msg.author.id); - if (ign == undefined) return await strings.unknown(msg); + let ign; + try { + ign = await util.ignForUser(args.name, msg.author.id); + } catch (err) { + return await strings.unknown(msg); + } - // peek const matchesView = new MatchesView(msg, ign); // wait for BE update - const waiter = api.subscribeUpdates(ign); - await api.upsearchPlayer(ign); + try { + const waiter = api.subscribeUpdates(ign); + await api.upsearchPlayer(ign); - do await matchesView.respond(); - while (await waiter.next() != undefined); + do await matchesView.respond(); + while (await waiter.next() != undefined); + } catch (err) { + console.log(err); + return await matchesView.error(err.error.err); + } } }; diff --git a/commands/vainsocial/me.js b/commands/vainsocial/me.js index e17afea..d2afb24 100644 --- a/commands/vainsocial/me.js +++ b/commands/vainsocial/me.js @@ -5,7 +5,8 @@ const Commando = require("discord.js-commando"), oneLine = require("common-tags").oneLine, api = require("../../api"), - util = require("../../util"); + util = require("../../util"), + RegisterView = require("../../views/register"); module.exports = class RegisterUserCommand extends Commando.Command { constructor(client) { @@ -33,8 +34,15 @@ Store your in game name for quicker access to other commands and for Guild manag // register a Discord account at VainSocial async run(msg, args) { util.trackAction(msg, "vainsocial-me", args.name); - await api.upsearchPlayer(ign); - await api.subscribeUpdates(ign).next(); - await new RegisterView(msg).respond(); + const registerView = new RegisterView(msg, args.name); + await api.upsearchPlayer(args.name); + try { + await api.subscribeUpdates(args.name).next(); + await api.setUser(msg.author.id, args.name); + } catch (err) { + console.log(err); + return await registerView.error(err.error.err); + } + await registerView.respond(); } }; diff --git a/commands/vainsocial/user.js b/commands/vainsocial/user.js index bfcc1a0..e251ad7 100644 --- a/commands/vainsocial/user.js +++ b/commands/vainsocial/user.js @@ -36,15 +36,24 @@ Display VainSocial lifetime statistics from Vainglory } async run(msg, args) { util.trackAction(msg, "vainsocial-user", args.name); - const ign = await util.ignForUser(args.name, msg.author.id); - if (ign == undefined) return await msg.say(strings.unknown(msg)); + let ign; + try { + ign = await util.ignForUser(args.name, msg.author.id); + } catch (err) { + return await new PlayerView(msg, args.name).error(strings.unknown(msg)); + } const playerView = new PlayerView(msg, ign); - // wait for BE update - const waiter = api.subscribeUpdates(ign); - await api.upsearchPlayer(ign); + try { + // wait for BE update + const waiter = api.subscribeUpdates(ign); + await api.upsearchPlayer(ign); - do await playerView.respond(); - while (await waiter.next() != undefined); + do await playerView.respond(); + while (await waiter.next() != undefined); + } catch (err) { + console.log(err); + return await playerView.error(err.error.err); + } } }; @@ -142,6 +142,12 @@ module.exports.paginate = function* chunks(arr, pagesize) { } // return ign, or associated ign, or undefined -module.exports.ignForUser = async (name, user_token) => +module.exports.ignForUser = async (name, user_token) => { // "?" is not accepted as user input, but the default for empty args - (name != "?")? name : await api.getUser(user_token); + if (name != "?") return name; + try { + return await api.getUser(user_token); + } catch (err) { + return undefined; + } +} diff --git a/views/guild_add.js b/views/guild_add.js deleted file mode 100644 index cb32dc3..0000000 --- a/views/guild_add.js +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/node -/* jshint esnext:true */ -"use strict"; - -const View = require("./view"), - util = require("../util"), - api = require("../api"), - strings = require("../strings"), - oneLine = require("common-tags").oneLine; - -const GuildAddView = module.exports; - -// match detail view -module.exports = class extends View { - constructor(msg, players) { - super(msg); - this.players = players; - } - - // players: obj, key=ign, value=player - async text(players) { - return Object.entries(players).map((tuple) => - (tuple[1] == undefined)? - `Loading ${tuple[0]}…` - : `Loaded ${tuple[0]}.` - ).join("\n"); - } - - async respond() { - this.response = await util.respond(this.msg, - await this.text(this.players), this.response); - return this.response; - }; -} diff --git a/views/match.js b/views/match.js index 8a04045..2dc55ec 100644 --- a/views/match.js +++ b/views/match.js @@ -15,13 +15,8 @@ const MatchView = module.exports; // match detail view module.exports = class extends View { - constructor(msg, matchid) { - super(msg); - this.matchid = matchid; - } - // return [[title, text], …] for rosters - static async text(match) { + async text(match) { let resps = []; for(let roster of match.rosters) { let winstr = "Won"; @@ -49,8 +44,8 @@ module.exports = class extends View { return embed; }; - async respond() { - const match = await api.getMatch(this.matchid); + async respond(matchid) { + const match = await api.getMatch(matchid); this.response = await util.respond(this.msg, await this.embed(match), this.response); return this.response; diff --git a/views/register.js b/views/register.js index 0e5ff71..9943299 100644 --- a/views/register.js +++ b/views/register.js @@ -2,7 +2,8 @@ /* jshint esnext:true */ "use strict"; -const View = require("./view"), +const emoji = require("discord-emoji"), + View = require("./view"), util = require("../util"), api = require("../api"), strings = require("../strings"), @@ -12,6 +13,11 @@ const RegisterView = module.exports; // user register view module.exports = class extends View { + constructor(msg, ign) { + super(msg); + this.ign = ign; + } + async text() { return `You are now registered at VainSocial, ${this.msg.author.mention}.`; } @@ -22,18 +28,18 @@ module.exports = class extends View { let reactions = {}; reactions[emoji.symbols.repeat] = async () => { util.trackAction(this.msg, "reaction-player"); - const ign = await util.ignForUser(undefined, this.msg.author.id); - await new PlayerView(this.msg, ign).respond(); + await new PlayerView(this.msg, this.ign).respond(); }; return reactions; } async respond() { - await api.setUser(msg.author.id, ign); + console.log("************************"); + console.log(await this.text()); this.response = await util.respond(this.msg, await this.text(), this.response); if (!this.hasButtons) { await util.reactionButtons(this.response, - await this.buttons(player, matches)); + await this.buttons()); this.hasButtons = true; } return this.response; diff --git a/views/view.js b/views/view.js index 3d3ae38..771e3db 100644 --- a/views/view.js +++ b/views/view.js @@ -33,7 +33,15 @@ module.exports = class { // reply with embed + buttons this.response = await util.respond(this.msg, await this.embed(), this.response); - await util.reactionButtons(this.response, await this.buttons(), this.msg); + if (!this.hasButtons) { + await util.reactionButtons(this.response, await this.buttons(), this.msg); + this.hasButtons = true; + } + return this.response; + } + async error(text) { + // reply with error + this.response = await util.respond(this.msg, text, this.response); return this.response; } }; |
