From 5b576a6c34710e4e981585e4c0349767041ff548 Mon Sep 17 00:00:00 2001 From: Julian Rabe Date: Sat, 13 Jun 2020 17:06:18 +0200 Subject: [PATCH] fix: Add more error capturing --- src/lib/Config.ts | 10 +++++++++- src/lib/Twitch2Ma.ts | 6 ++++-- src/lib/index.ts | 12 +++++++----- src/lib/sentry.ts | 17 ++++++++++------- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/lib/Config.ts b/src/lib/Config.ts index e2be887..4d45e0a 100644 --- a/src/lib/Config.ts +++ b/src/lib/Config.ts @@ -2,6 +2,14 @@ import Ajv = require("ajv"); import configSchema = require("../resources/config.schema.json"); import _ = require("lodash"); +export class ConfigError extends Error { + constructor(message: string) { + super(message); + Object.setPrototypeOf(this, ConfigError.prototype); + this.name = ConfigError.name; + } +} + export class Config { public readonly timeout: number; public readonly ma: MaConfig; @@ -20,7 +28,7 @@ export class Config { ajv.validate(configSchema, config); if(_.isArray(ajv.errors)) { - throw new Error(`Config file is invalid: ${ajv.errorsText(ajv.errors, {dataVar: "config"})}!`); + throw new ConfigError(`Config file is invalid: ${ajv.errorsText(ajv.errors, {dataVar: "config"})}!`); } this.timeout = config.timeout; diff --git a/src/lib/Twitch2Ma.ts b/src/lib/Twitch2Ma.ts index 3c73c7c..3cbb797 100644 --- a/src/lib/Twitch2Ma.ts +++ b/src/lib/Twitch2Ma.ts @@ -14,6 +14,8 @@ import CooldownPermission from "./permissions/CooldownPermission"; import OwnerPermission from "./permissions/OwnerPermission"; import ModeratorPermission from "./permissions/ModeratorPermission"; +import sentry from "./sentry"; + import type Telnet from "telnet-client"; import SourceMapSupport = require("source-map-support"); @@ -68,7 +70,7 @@ export default class Twitch2Ma extends EventEmitter { ors: "\r\n", }) .catch(() => { - throw new TelnetError("Could not connect to desk!") + throw new TelnetError("Could not connect to desk!"); }) .then(() => this.telnetLogin()) .then(() => this.initTwitch()); @@ -156,7 +158,7 @@ export default class Twitch2Ma extends EventEmitter { this.chatClient.say(channel, reason.viewerMessage); this.emit(this.onPermissionDenied, channel, user, reason.name); }) - .catch(() => this.stopWithError(new TelnetError("Sending telnet command failed!"))); + .catch(error => sentry(error, () => this.stopWithError(new TelnetError("Sending telnet command failed!")))); } } } diff --git a/src/lib/index.ts b/src/lib/index.ts index 48deb3d..ebb0510 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1,6 +1,7 @@ import {Command} from "commander"; -import Twitch2Ma from "./Twitch2Ma"; -import {Config} from "./Config"; +import Twitch2Ma, {TelnetError} from "./Twitch2Ma"; +import {Config, ConfigError} from "./Config"; +import sentry from "./sentry"; import Fs = require("fs"); import YAML = require("yaml"); @@ -20,7 +21,7 @@ export async function main() { return require("libnpm") .manifest(`${packageInformation.name}@latest`) .then(notifyUpdate) - .catch(() => warning("Could not get update information!")) + .catch((error: Error) => sentry(error, () => warning("Could not get update information!"))) .then(init); } @@ -35,7 +36,8 @@ function init(): void { .then(config => new Twitch2Ma(config)) .then(attachEventHandlers) .then(twitch2Ma => twitch2Ma.start()) - .catch(exitWithError); + .catch((error: ConfigError | TelnetError) => exitWithError(error)) + .catch(error => sentry(error, exitWithError)); }) .parse(process.argv); } @@ -94,7 +96,7 @@ export async function loadConfig(configFile: string): Promise { try { rawConfigObject = YAML.parse(rawConfigFile); } catch (ignored) { - throw new Error(`Config file ${configFile} is not a valid JSON or YAML file!`); + throw new ConfigError(`Config file ${configFile} is not a valid JSON or YAML file!`); } } diff --git a/src/lib/sentry.ts b/src/lib/sentry.ts index f749b06..a04780d 100644 --- a/src/lib/sentry.ts +++ b/src/lib/sentry.ts @@ -30,18 +30,21 @@ export function init(packageInformation: any) { version: process.version }); - if(process.env.NODE_ENV === "development" || process.env.NODE_ENV === "staging") { + if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "staging") { Sentry.setUser({username: os.userInfo().username}); } } - } catch(ignored){ + } catch (ignored) { } } -export default async function sentry(error: Error, messageHandler?: (error: Error) => any) { +export default function sentry(error: Error, messageHandler?: (error: Error) => any) { Sentry.captureException(error); - await Sentry.flush(); - if(messageHandler) { - messageHandler(error); - } + return Sentry.flush() + .catch(() => Promise.resolve()) + .then(() => { + if (messageHandler) { + messageHandler(error); + } + }); }