feat: improve error handling

This commit is contained in:
Isaac 2023-06-25 13:41:07 +01:00
parent 47fc7bde43
commit e8b95a2f31
No known key found for this signature in database
GPG Key ID: 0DE40AE37BBA5C33
10 changed files with 165 additions and 23 deletions

View File

@ -52,7 +52,7 @@
"@fastify/cookie": "^6.0.0", "@fastify/cookie": "^6.0.0",
"@fastify/jwt": "^5.0.1", "@fastify/jwt": "^5.0.1",
"@fastify/oauth2": "^5.1.0", "@fastify/oauth2": "^5.1.0",
"@prisma/client": "^4.14.1", "@prisma/client": "^4.16.1",
"boxen": "^7.1.0", "boxen": "^7.1.0",
"cryptr": "^6.2.0", "cryptr": "^6.2.0",
"discord.js": "^14.11.0", "discord.js": "^14.11.0",
@ -68,8 +68,9 @@
"node-dir": "^0.1.17", "node-dir": "^0.1.17",
"node-emoji": "^1.11.0", "node-emoji": "^1.11.0",
"object-diffy": "^1.0.4", "object-diffy": "^1.0.4",
"prisma": "^4.14.1", "prisma": "^4.16.1",
"semver": "^7.5.1", "semver": "^7.5.1",
"short-unique-id": "^4.4.4",
"spacetime": "^7.4.4", "spacetime": "^7.4.4",
"terminal-link": "^2.1.1", "terminal-link": "^2.1.1",
"yaml": "^1.10.2" "yaml": "^1.10.2"

View File

@ -23,8 +23,8 @@ dependencies:
specifier: ^5.1.0 specifier: ^5.1.0
version: 5.1.0 version: 5.1.0
'@prisma/client': '@prisma/client':
specifier: ^4.14.1 specifier: ^4.16.1
version: 4.15.0(prisma@4.15.0) version: 4.16.1(prisma@4.16.1)
boxen: boxen:
specifier: ^7.1.0 specifier: ^7.1.0
version: 7.1.0 version: 7.1.0
@ -71,11 +71,14 @@ dependencies:
specifier: ^1.0.4 specifier: ^1.0.4
version: 1.0.4 version: 1.0.4
prisma: prisma:
specifier: ^4.14.1 specifier: ^4.16.1
version: 4.15.0 version: 4.16.1
semver: semver:
specifier: ^7.5.1 specifier: ^7.5.1
version: 7.5.1 version: 7.5.1
short-unique-id:
specifier: ^4.4.4
version: 4.4.4
spacetime: spacetime:
specifier: ^7.4.4 specifier: ^7.4.4
version: 7.4.4 version: 7.4.4
@ -653,8 +656,8 @@ packages:
fastq: 1.15.0 fastq: 1.15.0
dev: true dev: true
/@prisma/client@4.15.0(prisma@4.15.0): /@prisma/client@4.16.1(prisma@4.16.1):
resolution: {integrity: sha512-xnROvyABcGiwqRNdrObHVZkD9EjkJYHOmVdlKy1yGgI+XOzvMzJ4tRg3dz1pUlsyhKxXGCnjIQjWW+2ur+YXuw==} resolution: {integrity: sha512-CoDHu7Bt+NuDo40ijoeHP79EHtECsPBTy3yte5Yo3op8TqXt/kV0OT5OrsWewKvQGKFMHhYQ+ePed3zzjYdGAw==}
engines: {node: '>=14.17'} engines: {node: '>=14.17'}
requiresBuild: true requiresBuild: true
peerDependencies: peerDependencies:
@ -663,16 +666,16 @@ packages:
prisma: prisma:
optional: true optional: true
dependencies: dependencies:
'@prisma/engines-version': 4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944 '@prisma/engines-version': 4.16.0-66.b20ead4d3ab9e78ac112966e242ded703f4a052c
prisma: 4.15.0 prisma: 4.16.1
dev: false dev: false
/@prisma/engines-version@4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944: /@prisma/engines-version@4.16.0-66.b20ead4d3ab9e78ac112966e242ded703f4a052c:
resolution: {integrity: sha512-sVOig4tjGxxlYaFcXgE71f/rtFhzyYrfyfNFUsxCIEJyVKU9rdOWIlIwQ2NQ7PntvGnn+x0XuFo4OC1jvPJKzg==} resolution: {integrity: sha512-tMWAF/qF00fbUH1HB4Yjmz6bjh7fzkb7Y3NRoUfMlHu6V+O45MGvqwYxqwBjn1BIUXkl3r04W351D4qdJjrgvA==}
dev: false dev: false
/@prisma/engines@4.15.0: /@prisma/engines@4.16.1:
resolution: {integrity: sha512-FTaOCGs0LL0OW68juZlGxFtYviZa4xdQj/rQEdat2txw0s3Vu/saAPKjNVXfIgUsGXmQ72HPgNr6935/P8FNAA==} resolution: {integrity: sha512-gpZG0kGGxfemgvK/LghHdBIz+crHkZjzszja94xp4oytpsXrgt/Ice82MvPsWMleVIniKuARrowtsIsim0PFJQ==}
requiresBuild: true requiresBuild: true
dev: false dev: false
@ -3069,13 +3072,13 @@ packages:
dev: true dev: true
optional: true optional: true
/prisma@4.15.0: /prisma@4.16.1:
resolution: {integrity: sha512-iKZZpobPl48gTcSZVawLMQ3lEy6BnXwtoMj7hluoGFYu2kQ6F9LBuBrUyF95zRVnNo8/3KzLXJXJ5TEnLSJFiA==} resolution: {integrity: sha512-C2Xm7yxHxjFjjscBEW4tmoraPHH/Vyu/A0XABdbaFtoiOZARsxvOM7rwc2iZ0qVxbh0bGBGBWZUSXO/52/nHBQ==}
engines: {node: '>=14.17'} engines: {node: '>=14.17'}
hasBin: true hasBin: true
requiresBuild: true requiresBuild: true
dependencies: dependencies:
'@prisma/engines': 4.15.0 '@prisma/engines': 4.16.1
dev: false dev: false
/process-nextick-args@2.0.1: /process-nextick-args@2.0.1:
@ -3390,6 +3393,11 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/short-unique-id@4.4.4:
resolution: {integrity: sha512-oLF1NCmtbiTWl2SqdXZQbo5KM1b7axdp0RgQLq8qCBBLoq+o3A5wmLrNM6bZIh54/a8BJ3l69kTXuxwZ+XCYuw==}
hasBin: true
dev: false
/signal-exit@3.0.7: /signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true dev: true

View File

@ -3,6 +3,11 @@ const {
EmbedBuilder, EmbedBuilder,
} = require('discord.js'); } = require('discord.js');
const { diff: getDiff } = require('object-diffy'); const { diff: getDiff } = require('object-diffy');
const ShortUniqueId = require('short-unique-id');
const uid = new ShortUniqueId();
const getSUID = () => uid.stamp(10);
const uuidRegex = /[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/g; const uuidRegex = /[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/g;
@ -235,6 +240,7 @@ async function logMessageEvent(client, {
module.exports = { module.exports = {
getLogChannel, getLogChannel,
getSUID,
logAdminEvent, logAdminEvent,
logMessageEvent, logMessageEvent,
logTicketEvent, logTicketEvent,

View File

@ -28,6 +28,7 @@ const {
decrypt, decrypt,
encrypt, encrypt,
} = new Cryptr(process.env.ENCRYPTION_KEY); } = new Cryptr(process.env.ENCRYPTION_KEY);
const { getSUID } = require('../logging');
/** /**
* @typedef {import('@prisma/client').Category & * @typedef {import('@prisma/client').Category &
@ -682,7 +683,7 @@ module.exports = class TicketManager {
userId: interaction.user.id, userId: interaction.user.id,
}); });
} catch (error) { } catch (error) {
const ref = require('crypto').randomUUID(); const ref = getSUID();
this.client.log.warn.tickets('An error occurred whilst creating ticket', channel.id); this.client.log.warn.tickets('An error occurred whilst creating ticket', channel.id);
this.client.log.error.tickets(ref); this.client.log.error.tickets(ref);
this.client.log.error.tickets(error); this.client.log.error.tickets(error);

View File

@ -0,0 +1,22 @@
const { Listener } = require('@eartharoid/dbf');
module.exports = class extends Listener {
constructor(client, options) {
super(client, {
...options,
emitter: client.autocomplete,
event: 'error',
});
}
async run({
completer,
error,
interaction,
}) {
this.client.log.error.autocomplete(`"${completer.id}" autocomplete execution error:`, {
error,
interaction,
});
}
};

View File

@ -3,6 +3,7 @@ const {
EmbedBuilder, EmbedBuilder,
codeBlock, codeBlock,
} = require('discord.js'); } = require('discord.js');
const { getSUID } = require('../../lib/logging');
module.exports = class extends Listener { module.exports = class extends Listener {
constructor(client, options) { constructor(client, options) {
@ -18,7 +19,7 @@ module.exports = class extends Listener {
error, error,
interaction, interaction,
}) { }) {
const ref = require('crypto').randomUUID(); const ref = getSUID();
this.client.log.error.buttons(ref); this.client.log.error.buttons(ref);
this.client.log.error.buttons(`"${button.id}" button execution error:`, error); this.client.log.error.buttons(`"${button.id}" button execution error:`, error);
let locale = null; let locale = null;
@ -39,7 +40,7 @@ module.exports = class extends Listener {
.addFields([ .addFields([
{ {
name: getMessage('misc.error.fields.identifier'), name: getMessage('misc.error.fields.identifier'),
value: codeBlock(ref), value: codeBlock(' ' + ref + ' '),
}, },
]), ]),
], ],

View File

@ -3,6 +3,7 @@ const {
EmbedBuilder, EmbedBuilder,
codeBlock, codeBlock,
} = require('discord.js'); } = require('discord.js');
const { getSUID } = require('../../lib/logging');
module.exports = class extends Listener { module.exports = class extends Listener {
constructor(client, options) { constructor(client, options) {
@ -18,7 +19,7 @@ module.exports = class extends Listener {
error, error,
interaction, interaction,
}) { }) {
const ref = require('crypto').randomUUID(); const ref = getSUID();
this.client.log.error.commands(ref); this.client.log.error.commands(ref);
this.client.log.error.commands(`"${command.name}" command execution error:`, error); this.client.log.error.commands(`"${command.name}" command execution error:`, error);
let locale = null; let locale = null;
@ -39,7 +40,7 @@ module.exports = class extends Listener {
.addFields([ .addFields([
{ {
name: getMessage('misc.error.fields.identifier'), name: getMessage('misc.error.fields.identifier'),
value: codeBlock(ref), value: codeBlock(' ' + ref + ' '),
}, },
]), ]),
], ],

View File

@ -0,0 +1,51 @@
const { Listener } = require('@eartharoid/dbf');
const {
EmbedBuilder,
codeBlock,
} = require('discord.js');
const { getSUID } = require('../../lib/logging');
module.exports = class extends Listener {
constructor(client, options) {
super(client, {
...options,
emitter: client.menus,
event: 'error',
});
}
async run({
menu,
error,
interaction,
}) {
const ref = getSUID();
this.client.log.error.menus(ref);
this.client.log.error.menus(`"${menu.id}" menu execution error:`, error);
let locale = null;
if (interaction.guild) {
locale = (await this.client.prisma.guild.findUnique({
select: { locale: true },
where: { id: interaction.guild.id },
})).locale;
}
const getMessage = this.client.i18n.getLocale(locale);
const data = {
components: [],
embeds: [
new EmbedBuilder()
.setColor('Orange')
.setTitle(getMessage('misc.error.title'))
.setDescription(getMessage('misc.error.description'))
.addFields([
{
name: getMessage('misc.error.fields.identifier'),
value: codeBlock(' ' + ref + ' '),
},
]),
],
};
interaction.reply(data).catch(() => interaction.editReply(data));
}
};

View File

@ -0,0 +1,51 @@
const { Listener } = require('@eartharoid/dbf');
const {
EmbedBuilder,
codeBlock,
} = require('discord.js');
const { getSUID } = require('../../lib/logging');
module.exports = class extends Listener {
constructor(client, options) {
super(client, {
...options,
emitter: client.modals,
event: 'error',
});
}
async run({
modal,
error,
interaction,
}) {
const ref = getSUID();
this.client.log.error.modals(ref);
this.client.log.error.modals(`"${modal.id}" modal execution error:`, error);
let locale = null;
if (interaction.guild) {
locale = (await this.client.prisma.guild.findUnique({
select: { locale: true },
where: { id: interaction.guild.id },
})).locale;
}
const getMessage = this.client.i18n.getLocale(locale);
const data = {
components: [],
embeds: [
new EmbedBuilder()
.setColor('Orange')
.setTitle(getMessage('misc.error.title'))
.setDescription(getMessage('misc.error.description'))
.addFields([
{
name: getMessage('misc.error.fields.identifier'),
value: codeBlock(' ' + ref + ' '),
},
]),
],
};
interaction.reply(data).catch(() => interaction.editReply(data));
}
};