summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschneefux <schneefux+commit@schneefux.xyz>2017-05-09 13:24:41 +0200
committerschneefux <schneefux+commit@schneefux.xyz>2017-05-09 13:24:41 +0200
commit54b59d1168e79c8706b164194bc1a48ec49726e4 (patch)
tree82b685a4e934ba237db3abcdde51d6f8e2c1b993
parent31b4764cd5233acb25f4d0027261fe83eaad6ec7 (diff)
downloaddiscordbot-54b59d1168e79c8706b164194bc1a48ec49726e4.tar.gz
discordbot-54b59d1168e79c8706b164194bc1a48ec49726e4.zip
error handling
-rw-r--r--api.js56
-rw-r--r--commands/vainsocial/guild_add.js3
-rw-r--r--commands/vainsocial/guild_fame_calc.js36
-rw-r--r--commands/vainsocial/guild_update.js28
-rw-r--r--commands/vainsocial/match.js32
-rw-r--r--commands/vainsocial/matches.js22
-rw-r--r--commands/vainsocial/me.js16
-rw-r--r--commands/vainsocial/user.js23
-rw-r--r--util.js10
-rw-r--r--views/guild_add.js34
-rw-r--r--views/match.js11
-rw-r--r--views/register.js16
-rw-r--r--views/view.js10
13 files changed, 144 insertions, 153 deletions
diff --git a/api.js b/api.js
index d303cab..74614c2 100644
--- a/api.js
+++ b/api.js
@@ -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);
+ }
}
};
diff --git a/util.js b/util.js
index a20cbaa..0f37918 100644
--- a/util.js
+++ b/util.js
@@ -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;
}
};