© 2026 Hedgehog Software, LLC
@sapphire/plugin-logger
import { container } from '@sapphire/framework'; import { Logger } from '@sapphire/plugin-logger'; import { captureException, captureMessage, Scope } from '@sentry/node'; import { redBright } from 'colorette'; export class SentinelLogger extends Logger { public infoTag(tag: string, value: unknown): void { super.info(`[${redBright(tag)}] ${value}`); } public sentryMessage(message: string, context?: NonNullable<unknown>): void { super.error(message); if (container.isDev) return; captureMessage(message, (scope): Scope => { if (context) scope.setExtra('context', context); return scope; }); } public sentryError(error: unknown, { message, context }: { message?: string; context?: NonNullable<unknown> } = {}): void { message ? super.error(message) : super.error(error); if (container.isDev) return; if (error instanceof Error) { captureException(error, (scope): Scope => { if (context) scope.setExtras(context); return scope; }); } } }
export class SentinelClient extends SapphireClient { public constructor() { super({ logger: { instance: new SentinelLogger({ level: LogLevel.Debug, join: '\n' }) } }); } }
@ApplyOptions<Listener.Options>({ event: Events.CommandApplicationCommandRegistryError }) export class ErrorListener extends Listener<typeof Events.CommandApplicationCommandRegistryError> { public run(error: Error, command: Command): void { const { name, location } = command; this.container.logger.sentryError(error, { message: `Encountered error while handling the command application command registry for ${name} (${location.full})`, context: command }); } }