PluginManager: catch errors during plugin flux handlers
This commit is contained in:
parent
b9392c3be2
commit
0b033aa51b
|
@ -169,7 +169,18 @@ export function subscribePluginFluxEvents(p: Plugin, fluxDispatcher: typeof Flux
|
||||||
|
|
||||||
logger.debug("Subscribing to flux events of plugin", p.name);
|
logger.debug("Subscribing to flux events of plugin", p.name);
|
||||||
for (const [event, handler] of Object.entries(p.flux)) {
|
for (const [event, handler] of Object.entries(p.flux)) {
|
||||||
fluxDispatcher.subscribe(event as FluxEvents, handler);
|
const wrappedHandler = p.flux[event] = function () {
|
||||||
|
try {
|
||||||
|
const res = handler.apply(p, arguments as any);
|
||||||
|
return res instanceof Promise
|
||||||
|
? res.catch(e => logger.error(`${p.name}: Error while handling ${event}\n`, e))
|
||||||
|
: res;
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(`${p.name}: Error while handling ${event}\n`, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fluxDispatcher.subscribe(event as FluxEvents, wrappedHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,104 +154,99 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MESSAGE_CREATE({ message, optimistic }: { message: Message; optimistic: boolean; }) {
|
MESSAGE_CREATE({ message, optimistic }: { message: Message; optimistic: boolean; }) {
|
||||||
// Apparently without this try/catch, discord's socket connection dies if any part of this errors
|
if (optimistic) return;
|
||||||
try {
|
const channel = ChannelStore.getChannel(message.channel_id);
|
||||||
if (optimistic) return;
|
if (!shouldNotify(message, message.channel_id)) return;
|
||||||
const channel = ChannelStore.getChannel(message.channel_id);
|
|
||||||
if (!shouldNotify(message, message.channel_id)) return;
|
|
||||||
|
|
||||||
const pingColor = settings.store.pingColor.replaceAll("#", "").trim();
|
const pingColor = settings.store.pingColor.replaceAll("#", "").trim();
|
||||||
const channelPingColor = settings.store.channelPingColor.replaceAll("#", "").trim();
|
const channelPingColor = settings.store.channelPingColor.replaceAll("#", "").trim();
|
||||||
let finalMsg = message.content;
|
let finalMsg = message.content;
|
||||||
let titleString = "";
|
let titleString = "";
|
||||||
|
|
||||||
if (channel.guild_id) {
|
if (channel.guild_id) {
|
||||||
const guild = GuildStore.getGuild(channel.guild_id);
|
const guild = GuildStore.getGuild(channel.guild_id);
|
||||||
titleString = `${message.author.username} (${guild.name}, #${channel.name})`;
|
titleString = `${message.author.username} (${guild.name}, #${channel.name})`;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
switch (channel.type) {
|
|
||||||
case ChannelTypes.DM:
|
|
||||||
titleString = message.author.username.trim();
|
|
||||||
break;
|
|
||||||
case ChannelTypes.GROUP_DM:
|
|
||||||
const channelName = channel.name.trim() ?? channel.rawRecipients.map(e => e.username).join(", ");
|
|
||||||
titleString = `${message.author.username} (${channelName})`;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.referenced_message) {
|
|
||||||
titleString += " (reply)";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.embeds.length > 0) {
|
|
||||||
finalMsg += " [embed] ";
|
|
||||||
if (message.content === "") {
|
|
||||||
finalMsg = "sent message embed(s)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.sticker_items) {
|
|
||||||
finalMsg += " [sticker] ";
|
|
||||||
if (message.content === "") {
|
|
||||||
finalMsg = "sent a sticker";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const images = message.attachments.filter(e =>
|
|
||||||
typeof e?.content_type === "string"
|
|
||||||
&& e?.content_type.startsWith("image")
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
images.forEach(img => {
|
|
||||||
finalMsg += ` [image: ${img.filename}] `;
|
|
||||||
});
|
|
||||||
|
|
||||||
message.attachments.filter(a => a && !a.content_type?.startsWith("image")).forEach(a => {
|
|
||||||
finalMsg += ` [attachment: ${a.filename}] `;
|
|
||||||
});
|
|
||||||
|
|
||||||
// make mentions readable
|
|
||||||
if (message.mentions.length > 0) {
|
|
||||||
finalMsg = finalMsg.replace(/<@!?(\d{17,20})>/g, (_, id) => `<color=#${pingColor}><b>@${UserStore.getUser(id)?.username || "unknown-user"}</color></b>`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// color role mentions (unity styling btw lol)
|
|
||||||
if (message.mention_roles.length > 0) {
|
|
||||||
for (const roleId of message.mention_roles) {
|
|
||||||
const role = GuildStore.getRole(channel.guild_id, roleId);
|
|
||||||
if (!role) continue;
|
|
||||||
const roleColor = role.colorString ?? `#${pingColor}`;
|
|
||||||
finalMsg = finalMsg.replace(`<@&${roleId}>`, `<b><color=${roleColor}>@${role.name}</color></b>`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// make emotes and channel mentions readable
|
|
||||||
const emoteMatches = finalMsg.match(new RegExp("(<a?:\\w+:\\d+>)", "g"));
|
|
||||||
const channelMatches = finalMsg.match(new RegExp("<(#\\d+)>", "g"));
|
|
||||||
|
|
||||||
if (emoteMatches) {
|
|
||||||
for (const eMatch of emoteMatches) {
|
|
||||||
finalMsg = finalMsg.replace(new RegExp(`${eMatch}`, "g"), `:${eMatch.split(":")[1]}:`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// color channel mentions
|
|
||||||
if (channelMatches) {
|
|
||||||
for (const cMatch of channelMatches) {
|
|
||||||
let channelId = cMatch.split("<#")[1];
|
|
||||||
channelId = channelId.substring(0, channelId.length - 1);
|
|
||||||
finalMsg = finalMsg.replace(new RegExp(`${cMatch}`, "g"), `<b><color=#${channelPingColor}>#${ChannelStore.getChannel(channelId).name}</color></b>`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldIgnoreForChannelType(channel)) return;
|
|
||||||
sendMsgNotif(titleString, finalMsg, message);
|
|
||||||
} catch (err) {
|
|
||||||
XSLog.error(`Failed to catch MESSAGE_CREATE: ${err}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch (channel.type) {
|
||||||
|
case ChannelTypes.DM:
|
||||||
|
titleString = message.author.username.trim();
|
||||||
|
break;
|
||||||
|
case ChannelTypes.GROUP_DM:
|
||||||
|
const channelName = channel.name.trim() ?? channel.rawRecipients.map(e => e.username).join(", ");
|
||||||
|
titleString = `${message.author.username} (${channelName})`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.referenced_message) {
|
||||||
|
titleString += " (reply)";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.embeds.length > 0) {
|
||||||
|
finalMsg += " [embed] ";
|
||||||
|
if (message.content === "") {
|
||||||
|
finalMsg = "sent message embed(s)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.sticker_items) {
|
||||||
|
finalMsg += " [sticker] ";
|
||||||
|
if (message.content === "") {
|
||||||
|
finalMsg = "sent a sticker";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const images = message.attachments.filter(e =>
|
||||||
|
typeof e?.content_type === "string"
|
||||||
|
&& e?.content_type.startsWith("image")
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
images.forEach(img => {
|
||||||
|
finalMsg += ` [image: ${img.filename}] `;
|
||||||
|
});
|
||||||
|
|
||||||
|
message.attachments.filter(a => a && !a.content_type?.startsWith("image")).forEach(a => {
|
||||||
|
finalMsg += ` [attachment: ${a.filename}] `;
|
||||||
|
});
|
||||||
|
|
||||||
|
// make mentions readable
|
||||||
|
if (message.mentions.length > 0) {
|
||||||
|
finalMsg = finalMsg.replace(/<@!?(\d{17,20})>/g, (_, id) => `<color=#${pingColor}><b>@${UserStore.getUser(id)?.username || "unknown-user"}</color></b>`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// color role mentions (unity styling btw lol)
|
||||||
|
if (message.mention_roles.length > 0) {
|
||||||
|
for (const roleId of message.mention_roles) {
|
||||||
|
const role = GuildStore.getRole(channel.guild_id, roleId);
|
||||||
|
if (!role) continue;
|
||||||
|
const roleColor = role.colorString ?? `#${pingColor}`;
|
||||||
|
finalMsg = finalMsg.replace(`<@&${roleId}>`, `<b><color=${roleColor}>@${role.name}</color></b>`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// make emotes and channel mentions readable
|
||||||
|
const emoteMatches = finalMsg.match(new RegExp("(<a?:\\w+:\\d+>)", "g"));
|
||||||
|
const channelMatches = finalMsg.match(new RegExp("<(#\\d+)>", "g"));
|
||||||
|
|
||||||
|
if (emoteMatches) {
|
||||||
|
for (const eMatch of emoteMatches) {
|
||||||
|
finalMsg = finalMsg.replace(new RegExp(`${eMatch}`, "g"), `:${eMatch.split(":")[1]}:`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// color channel mentions
|
||||||
|
if (channelMatches) {
|
||||||
|
for (const cMatch of channelMatches) {
|
||||||
|
let channelId = cMatch.split("<#")[1];
|
||||||
|
channelId = channelId.substring(0, channelId.length - 1);
|
||||||
|
finalMsg = finalMsg.replace(new RegExp(`${cMatch}`, "g"), `<b><color=#${channelPingColor}>#${ChannelStore.getChannel(channelId).name}</color></b>`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldIgnoreForChannelType(channel)) return;
|
||||||
|
sendMsgNotif(titleString, finalMsg, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -128,7 +128,7 @@ export interface PluginDef {
|
||||||
* Allows you to subscribe to Flux events
|
* Allows you to subscribe to Flux events
|
||||||
*/
|
*/
|
||||||
flux?: {
|
flux?: {
|
||||||
[E in FluxEvents]?: (event: any) => void;
|
[E in FluxEvents]?: (event: any) => void | Promise<void>;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Allows you to manipulate context menus
|
* Allows you to manipulate context menus
|
||||||
|
|
Loading…
Reference in a new issue