From efd0ae4c561448216aabe1f9b9d307fb22b7bd66 Mon Sep 17 00:00:00 2001 From: Mochamad Noor Syamsu Date: Mon, 20 Nov 2023 23:51:34 +0700 Subject: [PATCH 1/9] clean up ESLint warnings in notification package --- .../channel/__test__/pagerduty.test.ts | 4 +- packages/notification/channel/desktop.ts | 4 +- packages/notification/channel/index.ts | 57 ++++++++++--------- packages/notification/channel/monika-notif.ts | 4 +- packages/notification/channel/pagerduty.ts | 2 +- packages/notification/index.ts | 2 +- packages/notification/tsconfig.json | 1 + 7 files changed, 38 insertions(+), 36 deletions(-) diff --git a/packages/notification/channel/__test__/pagerduty.test.ts b/packages/notification/channel/__test__/pagerduty.test.ts index 3b4d0e3ec..d493c0c09 100644 --- a/packages/notification/channel/__test__/pagerduty.test.ts +++ b/packages/notification/channel/__test__/pagerduty.test.ts @@ -40,9 +40,7 @@ describe('PagerDuty notification', () => { it('should validate PagerDuty key', () => { // act - const error = validator.validate([ - { probeID: '65DDKmmB9mSaeE-8bMXRN' }, - ] as any) + const error = validator.validate([{ probeID: '65DDKmmB9mSaeE-8bMXRN' }]) // assert expect(error.error?.message).eq('"Key" is required') diff --git a/packages/notification/channel/desktop.ts b/packages/notification/channel/desktop.ts index 1d33e25a1..a9b609037 100644 --- a/packages/notification/channel/desktop.ts +++ b/packages/notification/channel/desktop.ts @@ -27,7 +27,7 @@ import Joi from 'joi' import { type as osType } from 'os' import type { NotificationMessage } from '.' -export const validator = Joi.any() +export const validator = Joi.object() export const send = async ( // actually do not need data property @@ -90,7 +90,7 @@ export const send = async ( function psEscape(str: string): string { let result = '' for (const ch of str) { - if (ch.charCodeAt(0) === 39) { + if (ch.codePointAt(0) === 39) { // single quote, escape it with another single quote result += ch } diff --git a/packages/notification/channel/index.ts b/packages/notification/channel/index.ts index 3ce180f92..ad5ec6810 100644 --- a/packages/notification/channel/index.ts +++ b/packages/notification/channel/index.ts @@ -22,7 +22,7 @@ * SOFTWARE. * **********************************************************************************/ -import type { AnySchema } from 'joi' +import type { ArraySchema, ObjectSchema } from 'joi' import * as dingtalk from './dingtalk' import * as discord from './discord' @@ -53,7 +53,7 @@ type BaseNotificationMessageMeta = { privateIpAddress: string publicIpAddress: string [key: string]: unknown - monikaInstance?: any + monikaInstance?: string version: string } @@ -89,9 +89,12 @@ export type NotificationMessage = { | NotificationStatusUpdateMessageMeta } -type NotificationChannel = { - validator: AnySchema - send: (notificationData: T, message: NotificationMessage) => Promise +type NotificationChannel = { + validator: ArraySchema | ObjectSchema + send: ( + notificationData: T | undefined, + message: NotificationMessage + ) => Promise sendWithCustomContent?: ( notificationData: T, customContent: T @@ -102,29 +105,29 @@ type NotificationChannel = { export type Notification = { id: string type: string - data: any + data: object | undefined } export const channels: Record = { - dingtalk, - discord, - desktop, - 'google-chat': googlechat, - gotify, - instatus, - lark, - mailgun, - 'monika-notif': monikaNotif, - opsgenie, - pagerduty, - pushbullet, - pushover, - sendgrid, - slack, - smtp, - teams, - telegram, - webhook, - whatsapp, - workplace, + dingtalk: dingtalk as NotificationChannel, + discord: discord as NotificationChannel, + desktop: desktop as NotificationChannel, + 'google-chat': googlechat as NotificationChannel, + gotify: gotify as NotificationChannel, + instatus: instatus as NotificationChannel, + lark: lark as NotificationChannel, + mailgun: mailgun as NotificationChannel, + 'monika-notif': monikaNotif as NotificationChannel, + opsgenie: opsgenie as NotificationChannel, + pagerduty: pagerduty as NotificationChannel, + pushbullet: pushbullet as NotificationChannel, + pushover: pushover as NotificationChannel, + sendgrid: sendgrid as NotificationChannel, + slack: slack as NotificationChannel, + smtp: smtp as NotificationChannel, + teams: teams as NotificationChannel, + telegram: telegram as NotificationChannel, + webhook: webhook as NotificationChannel, + whatsapp: whatsapp as NotificationChannel, + workplace: workplace as NotificationChannel, } diff --git a/packages/notification/channel/monika-notif.ts b/packages/notification/channel/monika-notif.ts index 92e1fab95..e76fd9606 100644 --- a/packages/notification/channel/monika-notif.ts +++ b/packages/notification/channel/monika-notif.ts @@ -31,7 +31,7 @@ type MonikaAlertNotifDataBody = { alert: string url: string time: string - monika: string + monika?: string } type MonikaStartAndTerminationNotifDataBody = { @@ -43,7 +43,7 @@ type MonikaStartAndTerminationNotifDataBody = { type MonikaStatusUpdateNotifDataBody = { type: 'status-update' time: string - monika: string + monika?: string numberOfProbes: string maxResponseTime: string minResponseTime: string diff --git a/packages/notification/channel/pagerduty.ts b/packages/notification/channel/pagerduty.ts index d6fe39a28..98dd02506 100644 --- a/packages/notification/channel/pagerduty.ts +++ b/packages/notification/channel/pagerduty.ts @@ -107,7 +107,7 @@ export async function send( function transformMessageToEventPayload( routingKey: string, message: NotificationMessage -): Record | null { +): Record | null { // https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTgw-events-api-v2-overview#pagerduty-common-event-format-pd-cef const { meta, summary } = message const { probeID, url, alertQuery, type, publicIpAddress } = meta diff --git a/packages/notification/index.ts b/packages/notification/index.ts index 9131e7b42..9c4c957ef 100644 --- a/packages/notification/index.ts +++ b/packages/notification/index.ts @@ -38,7 +38,7 @@ async function sendNotifications( } await channel.send(data, message) - } catch (error: any) { + } catch (error) { throw new Error( `Failed to send message using ${type}, please check your ${type} notification config.\nMessage: ${error?.message}` ) diff --git a/packages/notification/tsconfig.json b/packages/notification/tsconfig.json index 8da3b7b34..e263c3223 100644 --- a/packages/notification/tsconfig.json +++ b/packages/notification/tsconfig.json @@ -7,6 +7,7 @@ "outDir": "lib", "lib": ["ES2021", "DOM"], "strict": true, + "useUnknownInCatchVariables": false, "target": "es2017", "skipLibCheck": true, "esModuleInterop": true, From a540cf353128f43085263d4754ff530cc55b994b Mon Sep 17 00:00:00 2001 From: Mochamad Noor Syamsu Date: Tue, 21 Nov 2023 15:58:12 +0700 Subject: [PATCH 2/9] fix build --- src/components/config/get.test.ts | 2 +- src/components/logger/startup-message.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/config/get.test.ts b/src/components/config/get.test.ts index d9942ecbb..9a34885f9 100644 --- a/src/components/config/get.test.ts +++ b/src/components/config/get.test.ts @@ -60,7 +60,7 @@ describe('Add default notification', () => { // arrange const config: Partial = { notifications: [ - { id: '1', type: 'webhook', data: 'https://example.com' }, + { id: '1', type: 'webhook', data: { url: 'https://example.com' } }, ], } diff --git a/src/components/logger/startup-message.ts b/src/components/logger/startup-message.ts index 61f3cfdf2..bcd49fa81 100644 --- a/src/components/logger/startup-message.ts +++ b/src/components/logger/startup-message.ts @@ -174,7 +174,7 @@ function getAdditionalMessage(notification: Notification) { const { data, type } = notification const channel = channels[type] - if (!channel?.additionalStartupMessage) { + if (!channel?.additionalStartupMessage || !data) { return '' } From c68b9c8157ac5fc1164717ce7cefdaf3a1af10db Mon Sep 17 00:00:00 2001 From: Mochamad Noor Syamsu Date: Wed, 22 Nov 2023 12:32:20 +0700 Subject: [PATCH 3/9] add optional T[] parameter types --- packages/notification/channel/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/notification/channel/index.ts b/packages/notification/channel/index.ts index ad5ec6810..8aa8b1134 100644 --- a/packages/notification/channel/index.ts +++ b/packages/notification/channel/index.ts @@ -92,12 +92,12 @@ export type NotificationMessage = { type NotificationChannel = { validator: ArraySchema | ObjectSchema send: ( - notificationData: T | undefined, + notificationData: T | T[] | undefined, message: NotificationMessage ) => Promise sendWithCustomContent?: ( - notificationData: T, - customContent: T + notificationData: T | T[], + customContent: T | T[] ) => Promise additionalStartupMessage?: (notificationData: T) => string } From eb2ebdce1fce8f0805335c6ab4d3041d102276d1 Mon Sep 17 00:00:00 2001 From: Mochamad Noor Syamsu Date: Thu, 23 Nov 2023 19:23:49 +0700 Subject: [PATCH 4/9] clean up catch type any clause --- packages/notification/channel/instatus/index.ts | 4 ++-- packages/notification/validator/notification.ts | 2 +- src/components/config/index.test.ts | 2 +- src/components/config/index.ts | 4 ++-- src/components/config/parse-har.ts | 2 +- src/components/config/parse-postman.ts | 2 +- src/components/config/parse.ts | 2 +- src/components/config/validation/validator/probe.ts | 2 +- src/components/logger/history.ts | 6 +++--- src/components/probe/prober/icmp/request.ts | 2 +- src/components/probe/prober/mariadb/request.ts | 2 +- src/components/probe/prober/mongo/request.ts | 2 +- src/components/probe/prober/postgres/request.ts | 2 +- src/components/probe/prober/redis/request.ts | 2 +- src/components/probe/prober/socket/request.ts | 2 +- src/components/tls-checker/index.test.ts | 8 ++++---- src/events/subscribers/probe.ts | 2 +- src/jobs/summary-notification.ts | 6 +++--- src/plugins/metrics/prometheus/publisher.ts | 2 +- src/plugins/visualization/atlassian-status-page/index.ts | 4 ++-- src/symon/index.test.ts | 2 +- test/plugins/prometheus/index.test.ts | 2 +- tsconfig.json | 1 + 23 files changed, 33 insertions(+), 32 deletions(-) diff --git a/packages/notification/channel/instatus/index.ts b/packages/notification/channel/instatus/index.ts index ef751036c..66d67e145 100644 --- a/packages/notification/channel/instatus/index.ts +++ b/packages/notification/channel/instatus/index.ts @@ -138,7 +138,7 @@ async function createIncident( .then((res) => res?.data?.id) await insertIncidentToDatabase({ incidentID, probeID, status, url }) - } catch (error: any) { + } catch (error) { throw new Error( `${error?.message}${ error?.data ? `. ${error?.response?.data?.message}` : '' @@ -187,7 +187,7 @@ async function updateIncident( data, getAxiosConfig(apiKey) ) - } catch (error: any) { + } catch (error) { throw new Error( `${error?.message}${ error?.data ? `. ${error?.response?.data?.message}` : '' diff --git a/packages/notification/validator/notification.ts b/packages/notification/validator/notification.ts index e7f2bd7be..4e86cb4b5 100644 --- a/packages/notification/validator/notification.ts +++ b/packages/notification/validator/notification.ts @@ -43,7 +43,7 @@ export const validateNotification = async ( } await channel.validator.validateAsync(data) - } catch (error: any) { + } catch (error) { throw new Error(`${error?.message} (${type})`) } }) diff --git a/src/components/config/index.test.ts b/src/components/config/index.test.ts index 8819b14c2..307cf6bf3 100644 --- a/src/components/config/index.test.ts +++ b/src/components/config/index.test.ts @@ -147,7 +147,7 @@ describe('updateConfig', () => { try { // act await updateConfig({ probes: [] }) - } catch (error: any) { + } catch (error) { errorMessage = error.message } diff --git a/src/components/config/index.ts b/src/components/config/index.ts index 113093f44..c9289cc73 100644 --- a/src/components/config/index.ts +++ b/src/components/config/index.ts @@ -91,7 +91,7 @@ export const updateConfig = async ( if (validate) { try { validatedConfig = await validateConfig(config) - } catch (error: any) { + } catch (error) { if (isTestEnvironment) { // return error during tests throw new Error(error.message) @@ -216,7 +216,7 @@ function scheduleRemoteConfigFetcher({ } await updateConfig(mergeConfigs(defaultConfigs, nonDefaultConfig)) - } catch (error: any) { + } catch (error) { log.error(error?.message) } }, interval * 1000) diff --git a/src/components/config/parse-har.ts b/src/components/config/parse-har.ts index 3534664ce..adbae7134 100644 --- a/src/components/config/parse-har.ts +++ b/src/components/config/parse-har.ts @@ -78,7 +78,7 @@ export const parseHarFile = (fileContents: string): Config => { } return harConfig - } catch (error: any) { + } catch (error) { if (error.name === 'SyntaxError') { throw new Error('Har file is in invalid JSON format!') } diff --git a/src/components/config/parse-postman.ts b/src/components/config/parse-postman.ts index 8e69b582e..6fd6209a1 100644 --- a/src/components/config/parse-postman.ts +++ b/src/components/config/parse-postman.ts @@ -132,7 +132,7 @@ export const parseConfigFromPostman = (configString: string): Config => { const probes = generateProbesFromConfig(config, version) return { probes } - } catch (error: any) { + } catch (error) { if (error.name === 'SyntaxError') { throw new Error('Your Postman file contains an invalid JSON format!') } diff --git a/src/components/config/parse.ts b/src/components/config/parse.ts index 83ba714b6..dc491d876 100644 --- a/src/components/config/parse.ts +++ b/src/components/config/parse.ts @@ -87,7 +87,7 @@ export const parseConfig = async ( } return JSON.parse(configString) - } catch (error: any) { + } catch (error) { if (error.code === 'ENOENT' && error.path === source) { throw new Error(`Configuration file not found: ${source}.`) } diff --git a/src/components/config/validation/validator/probe.ts b/src/components/config/validation/validator/probe.ts index 44bc36ee1..0222c6430 100644 --- a/src/components/config/validation/validator/probe.ts +++ b/src/components/config/validation/validator/probe.ts @@ -321,7 +321,7 @@ export async function validateProbes(probes: Probe[]): Promise { return await schema.validateAsync(probes, { stripUnknown: true, }) - } catch (error: any) { + } catch (error) { throw new Error(`Monika configuration is invalid. Probe: ${error?.message}`) } } diff --git a/src/components/logger/history.ts b/src/components/logger/history.ts index 53b3a5590..59d385e75 100644 --- a/src/components/logger/history.ts +++ b/src/components/logger/history.ts @@ -172,7 +172,7 @@ export async function openLogfile(): Promise { setDatabase(db) await migrate() - } catch (error: any) { + } catch (error) { log.error("Warning: Can't open logfile. " + error.message) } } @@ -533,7 +533,7 @@ export async function saveProbeRequestLog({ ]) ) ) - } catch (error: any) { + } catch (error) { log.error("Error: Can't insert data into monika-log.db. " + error.message) } } @@ -577,7 +577,7 @@ export async function saveNotificationLog( notification.id, notification.type, ]) - } catch (error: any) { + } catch (error) { log.error("Error: Can't insert data into monika-log.db. " + error.message) } } diff --git a/src/components/probe/prober/icmp/request.ts b/src/components/probe/prober/icmp/request.ts index 563fb0f26..decc06f05 100644 --- a/src/components/probe/prober/icmp/request.ts +++ b/src/components/probe/prober/icmp/request.ts @@ -73,7 +73,7 @@ export async function icmpRequest( icmpResp.output = resp.output return processICMPRequestResult(icmpResp) - } catch (error: any) { + } catch (error) { console.error('icmp got error:', error) baseResponse.data = error // map error to data baseResponse.errMessage = error diff --git a/src/components/probe/prober/mariadb/request.ts b/src/components/probe/prober/mariadb/request.ts index cf3e88681..23ea2e30c 100644 --- a/src/components/probe/prober/mariadb/request.ts +++ b/src/components/probe/prober/mariadb/request.ts @@ -59,7 +59,7 @@ export async function mariaRequest( password: params.password, database: params.database, }) - } catch (error: any) { + } catch (error) { baseResponse.body = error.message baseResponse.errMessage = error baseResponse.result = probeRequestResult.failed diff --git a/src/components/probe/prober/mongo/request.ts b/src/components/probe/prober/mongo/request.ts index 52a5eccfd..ceef7f5ff 100644 --- a/src/components/probe/prober/mongo/request.ts +++ b/src/components/probe/prober/mongo/request.ts @@ -140,7 +140,7 @@ async function sendMongoRequest(params: MongoRequest): Promise { result.isAlive = true result.message = `${host}:${port} PONGED` } - } catch (error: any) { + } catch (error) { result.message = error } finally { if (client) { diff --git a/src/components/probe/prober/postgres/request.ts b/src/components/probe/prober/postgres/request.ts index 8e85b0c14..b62f19ee2 100644 --- a/src/components/probe/prober/postgres/request.ts +++ b/src/components/probe/prober/postgres/request.ts @@ -98,7 +98,7 @@ async function sendPsqlRequest(params: PostgresParam): Promise { await client.query('SELECT NOW()') result.message = 'postgres ok' result.isAlive = true - } catch (error: any) { + } catch (error) { result.message = error.message } finally { if (client !== false) { diff --git a/src/components/probe/prober/redis/request.ts b/src/components/probe/prober/redis/request.ts index 806df849d..5ac00b248 100644 --- a/src/components/probe/prober/redis/request.ts +++ b/src/components/probe/prober/redis/request.ts @@ -110,7 +110,7 @@ async function sendRedisRequest(params: Redis): Promise { result.isAlive = true result.message = `redis PONGED` } - } catch (error: any) { + } catch (error) { result.message = error } diff --git a/src/components/probe/prober/socket/request.ts b/src/components/probe/prober/socket/request.ts index d764c3af3..b0e4acdba 100644 --- a/src/components/probe/prober/socket/request.ts +++ b/src/components/probe/prober/socket/request.ts @@ -82,7 +82,7 @@ async function tcpCheck(tcpRequest: TCPRequest): Promise { status: 'UP', message: '', } - } catch (error: any) { + } catch (error) { return { duration: 0, responseData: null, diff --git a/src/components/tls-checker/index.test.ts b/src/components/tls-checker/index.test.ts index 85b0aeded..d28a98b68 100644 --- a/src/components/tls-checker/index.test.ts +++ b/src/components/tls-checker/index.test.ts @@ -34,7 +34,7 @@ describe('TLS Checker', () => { try { // act await checkTLS(url) - } catch (error: any) { + } catch (error) { // assert expect(error.message).to.include( `${url} security certificate has expired at` @@ -49,7 +49,7 @@ describe('TLS Checker', () => { try { // act await checkTLS(url) - } catch (error: any) { + } catch (error) { // assert expect(error.message).to.include( `${url} security certificate will expire at` @@ -68,7 +68,7 @@ describe('TLS Checker', () => { const result = await checkTLS(url) // assert expect(result).to.equal(null) - } catch (error: any) { + } catch (error) { // assert when example.com certificate will expire // because nothing lasts forever expect(error.message).to.include( @@ -91,7 +91,7 @@ describe('TLS Checker', () => { const result = await checkTLS(domainDef) // assert expect(result).to.equal(null) - } catch (error: any) { + } catch (error) { // assert when example.com certificate will expire // because nothing lasts forever expect(error.message).to.include( diff --git a/src/events/subscribers/probe.ts b/src/events/subscribers/probe.ts index e467c8427..458fea70f 100644 --- a/src/events/subscribers/probe.ts +++ b/src/events/subscribers/probe.ts @@ -58,7 +58,7 @@ eventEmitter.on( log.info( `Atlassian status page (${type}). id: ${incidentID}, probeID: ${probeID}, url: ${url}` ) - } catch (error: any) { + } catch (error) { log.error( `Atlassian status page (Error). probeID: ${probeID}, url: ${url}, probeState: ${probeState} error: ${error}` ) diff --git a/src/jobs/summary-notification.ts b/src/jobs/summary-notification.ts index bf95c1fed..256689ff4 100644 --- a/src/jobs/summary-notification.ts +++ b/src/jobs/summary-notification.ts @@ -123,7 +123,7 @@ ${tweetMessage} if (checkIs24HourHasPassed()) { resetlogs() } - } catch (error: any) { + } catch (error) { log.error(`Summary notification: ${error.message}`) } } @@ -144,7 +144,7 @@ function readPidFile(): PidObject { let data = '' try { data = fs.readFileSync('monika.pid', 'utf8') - } catch (error: any) { + } catch (error) { if (error.code === 'ENOENT') { log.info( 'Could not find the file: monika.pid. Monika is probably not running or ran from a diffent directory' @@ -245,7 +245,7 @@ export async function printSummary(cliConfig: IConfig): Promise { App version : ${cliConfig.userAgent} `) - } catch (error: any) { + } catch (error) { log.error(`Summary notification: ${error.message}`) } } diff --git a/src/plugins/metrics/prometheus/publisher.ts b/src/plugins/metrics/prometheus/publisher.ts index 2e493ac12..fc71c985f 100644 --- a/src/plugins/metrics/prometheus/publisher.ts +++ b/src/plugins/metrics/prometheus/publisher.ts @@ -45,7 +45,7 @@ export function startPrometheusMetricsServer(port: number): void { const prometheusMetrics = await register.metrics() res.status(200).end(prometheusMetrics) - } catch (error: any) { + } catch (error) { res.status(500).json({ message: error.message }) } }) diff --git a/src/plugins/visualization/atlassian-status-page/index.ts b/src/plugins/visualization/atlassian-status-page/index.ts index 1d376ac70..fa4d91488 100644 --- a/src/plugins/visualization/atlassian-status-page/index.ts +++ b/src/plugins/visualization/atlassian-status-page/index.ts @@ -133,7 +133,7 @@ export class AtlassianStatusPageAPI { await insertIncidentToDatabase({ incidentID, probeID, status, url }) return incidentID - } catch (error: any) { + } catch (error) { throw new Error( `${error?.message}${ error?.data ? `. ${error?.response?.data?.message}` : '' @@ -169,7 +169,7 @@ export class AtlassianStatusPageAPI { data, this.axiosConfig ) - } catch (error: any) { + } catch (error) { throw new Error( `${error?.message}${ error?.data ? `. ${error?.response?.data?.message}` : '' diff --git a/src/symon/index.test.ts b/src/symon/index.test.ts index 4f885436a..1bdb86450 100644 --- a/src/symon/index.test.ts +++ b/src/symon/index.test.ts @@ -235,7 +235,7 @@ describe('Symon initiate', () => { try { // act await symon.initiate() - } catch (error: any) { + } catch (error) { errorMessage = error?.message } diff --git a/test/plugins/prometheus/index.test.ts b/test/plugins/prometheus/index.test.ts index b39ed9dd9..520c8efa1 100644 --- a/test/plugins/prometheus/index.test.ts +++ b/test/plugins/prometheus/index.test.ts @@ -76,7 +76,7 @@ describe('Prometheus plugin', () => { try { // act await axios.post('http://localhost:4446/metrics') - } catch (error: any) { + } catch (error) { // assert expect(error.response.status).to.equal(405) } diff --git a/tsconfig.json b/tsconfig.json index 61375d3b4..7eaf84c8d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "declaration": true, "sourceMap": true, "baseUrl": ".", + "useUnknownInCatchVariables": false, "typeRoots": ["node_modules/@types", "custom_types"], "lib": ["ES2021.String"], "composite": true From ef33ab83a931cabd3a6c37f5ba36254f564d563e Mon Sep 17 00:00:00 2001 From: Mochamad Noor Syamsu Date: Fri, 1 Dec 2023 00:45:41 +0700 Subject: [PATCH 5/9] clean up sendWithCustomContent signature --- packages/notification/channel/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/notification/channel/index.ts b/packages/notification/channel/index.ts index 8aa8b1134..17dd8b374 100644 --- a/packages/notification/channel/index.ts +++ b/packages/notification/channel/index.ts @@ -89,7 +89,7 @@ export type NotificationMessage = { | NotificationStatusUpdateMessageMeta } -type NotificationChannel = { +type NotificationChannel = { validator: ArraySchema | ObjectSchema send: ( notificationData: T | T[] | undefined, @@ -97,7 +97,7 @@ type NotificationChannel = { ) => Promise sendWithCustomContent?: ( notificationData: T | T[], - customContent: T | T[] + customContent: U | U[] ) => Promise additionalStartupMessage?: (notificationData: T) => string } From 85010ff1b09b2376fbe38f81b3eeb2489c30cdc7 Mon Sep 17 00:00:00 2001 From: Mochamad Noor Syamsu Date: Fri, 1 Dec 2023 21:02:50 +0700 Subject: [PATCH 6/9] handle catch type --- .../channel/__test__/discord.test.ts | 4 +-- .../channel/__test__/mailgun.test.ts | 4 +-- .../channel/__test__/monika-notif.test.ts | 4 +-- .../channel/__test__/pushbullet.test.ts | 2 +- .../channel/__test__/sengrid.test.ts | 2 +- .../channel/__test__/slack.test.ts | 4 +-- .../channel/__test__/teams.test.ts | 4 +-- .../channel/__test__/telegram.test.ts | 4 +-- .../channel/__test__/webhook.test.ts | 4 +-- .../channel/__test__/workplace.test.ts | 4 +-- packages/notification/tsconfig.json | 1 - .../config/__tests__/parse-postman.test.ts | 2 +- src/components/tls-checker/index.test.ts | 27 +++++++++---------- src/symon/index.test.ts | 5 ++-- test/plugins/prometheus/index.test.ts | 8 +++--- tsconfig.json | 1 - 16 files changed, 40 insertions(+), 40 deletions(-) diff --git a/packages/notification/channel/__test__/discord.test.ts b/packages/notification/channel/__test__/discord.test.ts index 8ab6cb5d1..0ffc0c8ef 100644 --- a/packages/notification/channel/__test__/discord.test.ts +++ b/packages/notification/channel/__test__/discord.test.ts @@ -49,7 +49,7 @@ describe('notificationChecker - discordNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Discord URL" is not allowed to be empty' expect(() => { @@ -68,7 +68,7 @@ describe('notificationChecker - discordNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Discord URL" must be a valid uri' expect(() => { diff --git a/packages/notification/channel/__test__/mailgun.test.ts b/packages/notification/channel/__test__/mailgun.test.ts index 4057f32a3..a764ab5e2 100644 --- a/packages/notification/channel/__test__/mailgun.test.ts +++ b/packages/notification/channel/__test__/mailgun.test.ts @@ -27,7 +27,7 @@ describe('notificationChecker - mailgunNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Mailgun API Key" is not allowed to be empty' expect(() => { @@ -48,7 +48,7 @@ describe('notificationChecker - mailgunNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Mailgun Domain" is not allowed to be empty' expect(() => { diff --git a/packages/notification/channel/__test__/monika-notif.test.ts b/packages/notification/channel/__test__/monika-notif.test.ts index 2a04bf20a..bf48c073d 100644 --- a/packages/notification/channel/__test__/monika-notif.test.ts +++ b/packages/notification/channel/__test__/monika-notif.test.ts @@ -25,7 +25,7 @@ describe('notificationChecker - MonikaNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Monika Notification URL" is not allowed to be empty' expect(() => { @@ -44,7 +44,7 @@ describe('notificationChecker - MonikaNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Monika Notification URL" must be a valid uri' expect(() => { diff --git a/packages/notification/channel/__test__/pushbullet.test.ts b/packages/notification/channel/__test__/pushbullet.test.ts index 3f1bd4803..bf6dd3e65 100644 --- a/packages/notification/channel/__test__/pushbullet.test.ts +++ b/packages/notification/channel/__test__/pushbullet.test.ts @@ -49,7 +49,7 @@ describe('notificationChecker - pushbulletNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Pushbullet token" is not allowed to be empty' expect(() => { diff --git a/packages/notification/channel/__test__/sengrid.test.ts b/packages/notification/channel/__test__/sengrid.test.ts index b700d664d..fe3ef56e8 100644 --- a/packages/notification/channel/__test__/sengrid.test.ts +++ b/packages/notification/channel/__test__/sengrid.test.ts @@ -27,7 +27,7 @@ describe('notificationChecker - sendgridNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"SendGrid API Key" is not allowed to be empty' expect(() => { diff --git a/packages/notification/channel/__test__/slack.test.ts b/packages/notification/channel/__test__/slack.test.ts index 1da1cc088..3b5a5584f 100644 --- a/packages/notification/channel/__test__/slack.test.ts +++ b/packages/notification/channel/__test__/slack.test.ts @@ -23,7 +23,7 @@ describe('notificationChecker - slackNotification', () => { data: { url: '' }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Slack URL" is not allowed to be empty' expect(() => { @@ -42,7 +42,7 @@ describe('notificationChecker - slackNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Slack URL" must be a valid uri' expect(() => { diff --git a/packages/notification/channel/__test__/teams.test.ts b/packages/notification/channel/__test__/teams.test.ts index 60c6a3dd7..b22e20167 100644 --- a/packages/notification/channel/__test__/teams.test.ts +++ b/packages/notification/channel/__test__/teams.test.ts @@ -23,7 +23,7 @@ describe('notificationChecker - teamsNotification', () => { data: { url: '' }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Teams URL" is not allowed to be empty' expect(() => { @@ -42,7 +42,7 @@ describe('notificationChecker - teamsNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Teams URL" must be a valid uri' expect(() => { diff --git a/packages/notification/channel/__test__/telegram.test.ts b/packages/notification/channel/__test__/telegram.test.ts index 893d31e26..fdbbcf1c1 100644 --- a/packages/notification/channel/__test__/telegram.test.ts +++ b/packages/notification/channel/__test__/telegram.test.ts @@ -27,7 +27,7 @@ describe('notificationChecker - telegramNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Telegram Group ID" is not allowed to be empty' expect(() => { @@ -47,7 +47,7 @@ describe('notificationChecker - telegramNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Telegram Bot Token" is not allowed to be empty' expect(() => { diff --git a/packages/notification/channel/__test__/webhook.test.ts b/packages/notification/channel/__test__/webhook.test.ts index 8b5d6674e..085c34a40 100644 --- a/packages/notification/channel/__test__/webhook.test.ts +++ b/packages/notification/channel/__test__/webhook.test.ts @@ -44,7 +44,7 @@ describe('notificationChecker - webhookNotification', () => { data: { url: '' }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Webhook URL" is not allowed to be empty' expect(() => { @@ -63,7 +63,7 @@ describe('notificationChecker - webhookNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Webhook URL" must be a valid uri' expect(() => { diff --git a/packages/notification/channel/__test__/workplace.test.ts b/packages/notification/channel/__test__/workplace.test.ts index bc5a954ba..638490eef 100644 --- a/packages/notification/channel/__test__/workplace.test.ts +++ b/packages/notification/channel/__test__/workplace.test.ts @@ -27,7 +27,7 @@ describe('notificationChecker - workplaceNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Workplace Thread ID" is not allowed to be empty' expect(() => { @@ -47,7 +47,7 @@ describe('notificationChecker - workplaceNotification', () => { }, }, ]) - } catch (error) { + } catch (error: unknown) { const message = '"Workplace Access Token" is not allowed to be empty' expect(() => { diff --git a/packages/notification/tsconfig.json b/packages/notification/tsconfig.json index e263c3223..8da3b7b34 100644 --- a/packages/notification/tsconfig.json +++ b/packages/notification/tsconfig.json @@ -7,7 +7,6 @@ "outDir": "lib", "lib": ["ES2021", "DOM"], "strict": true, - "useUnknownInCatchVariables": false, "target": "es2017", "skipLibCheck": true, "esModuleInterop": true, diff --git a/src/components/config/__tests__/parse-postman.test.ts b/src/components/config/__tests__/parse-postman.test.ts index 5aa5f87e9..5c4be521c 100644 --- a/src/components/config/__tests__/parse-postman.test.ts +++ b/src/components/config/__tests__/parse-postman.test.ts @@ -35,7 +35,7 @@ describe('parseConfigFromPostman', () => { it('throws invalid JSON format', () => { try { parseConfigFromPostman('../fetch.ts') - } catch (error) { + } catch (error: unknown) { expect(() => { throw error }).to.throw('Your Postman file contains an invalid JSON format!') diff --git a/src/components/tls-checker/index.test.ts b/src/components/tls-checker/index.test.ts index d28a98b68..1a5a1dcd6 100644 --- a/src/components/tls-checker/index.test.ts +++ b/src/components/tls-checker/index.test.ts @@ -24,6 +24,7 @@ import { expect } from '@oclif/test' import { checkTLS } from '../tls-checker' +import { getErrorMessage } from 'src/utils/catch-handler' describe('TLS Checker', () => { describe('fail attempt', () => { @@ -34,11 +35,10 @@ describe('TLS Checker', () => { try { // act await checkTLS(url) - } catch (error) { + } catch (error: unknown) { + const message = getErrorMessage(error) // assert - expect(error.message).to.include( - `${url} security certificate has expired at` - ) + expect(message).to.include(`${url} security certificate has expired at`) } }) @@ -49,11 +49,10 @@ describe('TLS Checker', () => { try { // act await checkTLS(url) - } catch (error) { + } catch (error: unknown) { + const message = getErrorMessage(error) // assert - expect(error.message).to.include( - `${url} security certificate will expire at` - ) + expect(message).to.include(`${url} security certificate will expire at`) } }) }) @@ -68,12 +67,11 @@ describe('TLS Checker', () => { const result = await checkTLS(url) // assert expect(result).to.equal(null) - } catch (error) { + } catch (error: unknown) { + const message = getErrorMessage(error) // assert when example.com certificate will expire // because nothing lasts forever - expect(error.message).to.include( - `${url} security certificate will expire at` - ) + expect(message).to.include(`${url} security certificate will expire at`) } }) @@ -91,10 +89,11 @@ describe('TLS Checker', () => { const result = await checkTLS(domainDef) // assert expect(result).to.equal(null) - } catch (error) { + } catch (error: unknown) { + const message = getErrorMessage(error) // assert when example.com certificate will expire // because nothing lasts forever - expect(error.message).to.include( + expect(message).to.include( `${domainDef.domain} security certificate will expire at` ) } diff --git a/src/symon/index.test.ts b/src/symon/index.test.ts index 1bdb86450..b64c15b1b 100644 --- a/src/symon/index.test.ts +++ b/src/symon/index.test.ts @@ -34,6 +34,7 @@ import SymonClient from '.' import { validateProbes } from '../components/config/validation' import * as loggerHistory from '../components/logger/history' import { setContext } from '../context' +import { getErrorMessage } from 'src/utils/catch-handler' let getUnreportedLogsStub: sinon.SinonStub @@ -235,8 +236,8 @@ describe('Symon initiate', () => { try { // act await symon.initiate() - } catch (error) { - errorMessage = error?.message + } catch (error: unknown) { + errorMessage = getErrorMessage(error) } // assert diff --git a/test/plugins/prometheus/index.test.ts b/test/plugins/prometheus/index.test.ts index 520c8efa1..25b9fe7fb 100644 --- a/test/plugins/prometheus/index.test.ts +++ b/test/plugins/prometheus/index.test.ts @@ -25,7 +25,7 @@ import { expect, test } from '@oclif/test' import path from 'path' import cmd from '../../../src/commands/monika' -import axios from 'axios' +import axios, { AxiosError } from 'axios' const { resolve } = path @@ -76,9 +76,11 @@ describe('Prometheus plugin', () => { try { // act await axios.post('http://localhost:4446/metrics') - } catch (error) { + } catch (error: unknown) { + const statusCode = + error instanceof AxiosError ? error.response?.status : -1 // assert - expect(error.response.status).to.equal(405) + expect(statusCode).to.equal(405) } // eslint-disable-next-line unicorn/no-process-exit, no-process-exit diff --git a/tsconfig.json b/tsconfig.json index 7eaf84c8d..61375d3b4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,6 @@ "declaration": true, "sourceMap": true, "baseUrl": ".", - "useUnknownInCatchVariables": false, "typeRoots": ["node_modules/@types", "custom_types"], "lib": ["ES2021.String"], "composite": true From ec0296413275314c57aa209cdfd3fa7d47b4e3ba Mon Sep 17 00:00:00 2001 From: Mochamad Noor Syamsu Date: Fri, 1 Dec 2023 21:03:03 +0700 Subject: [PATCH 7/9] add catch-handler.ts --- src/utils/catch-handler.ts | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/utils/catch-handler.ts diff --git a/src/utils/catch-handler.ts b/src/utils/catch-handler.ts new file mode 100644 index 000000000..0006b48b7 --- /dev/null +++ b/src/utils/catch-handler.ts @@ -0,0 +1,54 @@ +/********************************************************************************** + * MIT License * + * * + * Copyright (c) 2021 Hyperjump Technology * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy * + * of this software and associated documentation files (the "Software"), to deal * + * in the Software without restriction, including without limitation the rights * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included in all * + * copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * + * SOFTWARE. * + **********************************************************************************/ + +// Credits to Kent C. Dodds +// taken from https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript +type ErrorWithMessage = { + message: string +} + +function isErrorWithMessage(error: unknown): error is ErrorWithMessage { + return ( + typeof error === 'object' && + error !== null && + 'message' in error && + typeof (error as Record).message === 'string' + ) +} + +function toErrorWithMessage(maybeError: unknown): ErrorWithMessage { + if (isErrorWithMessage(maybeError)) return maybeError + + try { + return new Error(JSON.stringify(maybeError)) + } catch { + // fallback in case there's an error stringifying the maybeError + // like with circular references for example. + return new Error(String(maybeError)) + } +} + +export function getErrorMessage(error: unknown) { + return toErrorWithMessage(error).message +} From d080271c89612e2cf21a45f413370ede664fa86e Mon Sep 17 00:00:00 2001 From: Mochamad Noor Syamsu Date: Fri, 1 Dec 2023 21:26:04 +0700 Subject: [PATCH 8/9] fix build --- package-lock.json | 2 +- .../notification/channel/instatus/index.ts | 20 ++++--- packages/notification/channel/whatsapp.ts | 4 +- packages/notification/index.ts | 6 ++- .../notification/utils/catch-error-handler.ts | 54 +++++++++++++++++++ .../notification/validator/notification.ts | 6 ++- .../config/__tests__/parse-postman.test.ts | 2 +- src/components/config/index.test.ts | 2 +- src/components/config/parse-har.ts | 2 +- src/components/config/parse-postman.ts | 2 +- src/components/config/parse.ts | 2 +- .../config/validation/validator/probe.ts | 2 +- src/components/logger/history.ts | 6 +-- src/components/probe/prober/icmp/request.ts | 2 +- src/components/probe/prober/mongo/request.ts | 2 +- .../probe/prober/postgres/request.ts | 2 +- src/components/probe/prober/redis/request.ts | 2 +- src/components/probe/prober/socket/request.ts | 2 +- src/events/subscribers/probe.ts | 2 +- src/jobs/summary-notification.ts | 6 +-- src/plugins/metrics/prometheus/publisher.ts | 2 +- src/plugins/updater/index.ts | 4 +- .../atlassian-status-page/index.ts | 4 +- 23 files changed, 101 insertions(+), 37 deletions(-) create mode 100644 packages/notification/utils/catch-error-handler.ts diff --git a/package-lock.json b/package-lock.json index 504b62e93..555231e09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18912,7 +18912,7 @@ }, "packages/notification": { "name": "@hyperjumptech/monika-notification", - "version": "1.15.11", + "version": "1.15.12", "license": "MIT", "dependencies": { "@sendgrid/mail": "^7.4.2", diff --git a/packages/notification/channel/instatus/index.ts b/packages/notification/channel/instatus/index.ts index 66d67e145..4eeb45712 100644 --- a/packages/notification/channel/instatus/index.ts +++ b/packages/notification/channel/instatus/index.ts @@ -22,7 +22,7 @@ * SOFTWARE. * **********************************************************************************/ -import axios from 'axios' +import axios, { AxiosError } from 'axios' import Joi from 'joi' import { findIncident, @@ -138,10 +138,13 @@ async function createIncident( .then((res) => res?.data?.id) await insertIncidentToDatabase({ incidentID, probeID, status, url }) - } catch (error) { + } catch (error: unknown) { + const axiosError = error instanceof AxiosError ? error : new AxiosError() throw new Error( - `${error?.message}${ - error?.data ? `. ${error?.response?.data?.message}` : '' + `${axiosError?.message}${ + axiosError?.response?.data + ? `. ${axiosError?.response?.data?.message}` + : '' }` ) } @@ -187,10 +190,13 @@ async function updateIncident( data, getAxiosConfig(apiKey) ) - } catch (error) { + } catch (error: unknown) { + const axiosError = error instanceof AxiosError ? error : new AxiosError() throw new Error( - `${error?.message}${ - error?.data ? `. ${error?.response?.data?.message}` : '' + `${axiosError.message}${ + axiosError?.response?.data + ? `. ${axiosError?.response?.data?.message}` + : '' }` ) } diff --git a/packages/notification/channel/whatsapp.ts b/packages/notification/channel/whatsapp.ts index 9059e8fe8..a72f36568 100644 --- a/packages/notification/channel/whatsapp.ts +++ b/packages/notification/channel/whatsapp.ts @@ -112,7 +112,7 @@ async function sendTextMessage({ }, }, }) - } catch (error) { + } catch (error: unknown) { throw new Error( `Something wrong with your recipient number, Please check your country code: ${recipient} ${error}` ) @@ -147,7 +147,7 @@ async function loginUser({ } return loginResp.users[0].token - } catch (error) { + } catch (error: unknown) { throw new Error( `Something wrong with your whatsapp config please check again. error: ${error}` ) diff --git a/packages/notification/index.ts b/packages/notification/index.ts index 9c4c957ef..a25d83301 100644 --- a/packages/notification/index.ts +++ b/packages/notification/index.ts @@ -23,6 +23,7 @@ **********************************************************************************/ import { channels, Notification, NotificationMessage } from './channel' +import { getErrorMessage } from './utils/catch-error-handler' async function sendNotifications( notifications: Notification[], @@ -38,9 +39,10 @@ async function sendNotifications( } await channel.send(data, message) - } catch (error) { + } catch (error: unknown) { + const message = getErrorMessage(error) throw new Error( - `Failed to send message using ${type}, please check your ${type} notification config.\nMessage: ${error?.message}` + `Failed to send message using ${type}, please check your ${type} notification config.\nMessage: ${message}` ) } }) diff --git a/packages/notification/utils/catch-error-handler.ts b/packages/notification/utils/catch-error-handler.ts new file mode 100644 index 000000000..0006b48b7 --- /dev/null +++ b/packages/notification/utils/catch-error-handler.ts @@ -0,0 +1,54 @@ +/********************************************************************************** + * MIT License * + * * + * Copyright (c) 2021 Hyperjump Technology * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy * + * of this software and associated documentation files (the "Software"), to deal * + * in the Software without restriction, including without limitation the rights * + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included in all * + * copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * + * SOFTWARE. * + **********************************************************************************/ + +// Credits to Kent C. Dodds +// taken from https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript +type ErrorWithMessage = { + message: string +} + +function isErrorWithMessage(error: unknown): error is ErrorWithMessage { + return ( + typeof error === 'object' && + error !== null && + 'message' in error && + typeof (error as Record).message === 'string' + ) +} + +function toErrorWithMessage(maybeError: unknown): ErrorWithMessage { + if (isErrorWithMessage(maybeError)) return maybeError + + try { + return new Error(JSON.stringify(maybeError)) + } catch { + // fallback in case there's an error stringifying the maybeError + // like with circular references for example. + return new Error(String(maybeError)) + } +} + +export function getErrorMessage(error: unknown) { + return toErrorWithMessage(error).message +} diff --git a/packages/notification/validator/notification.ts b/packages/notification/validator/notification.ts index 4e86cb4b5..5ecc22358 100644 --- a/packages/notification/validator/notification.ts +++ b/packages/notification/validator/notification.ts @@ -23,6 +23,7 @@ **********************************************************************************/ import { channels, type Notification } from '../channel' +import { getErrorMessage } from '../utils/catch-error-handler' export const validateNotification = async ( notifications: Notification[] @@ -43,8 +44,9 @@ export const validateNotification = async ( } await channel.validator.validateAsync(data) - } catch (error) { - throw new Error(`${error?.message} (${type})`) + } catch (error: unknown) { + const message = getErrorMessage(error) + throw new Error(`${message} (${type})`) } }) ) diff --git a/src/components/config/__tests__/parse-postman.test.ts b/src/components/config/__tests__/parse-postman.test.ts index 5c4be521c..4a267f50f 100644 --- a/src/components/config/__tests__/parse-postman.test.ts +++ b/src/components/config/__tests__/parse-postman.test.ts @@ -47,7 +47,7 @@ describe('parseConfigFromPostman', () => { const collectionStr = JSON.stringify(unsupportedCollection) parseConfigFromPostman(collectionStr) - } catch (error) { + } catch (error: unknown) { expect(() => { throw error }).to.throw( diff --git a/src/components/config/index.test.ts b/src/components/config/index.test.ts index f8987b8fb..3c1a7d447 100644 --- a/src/components/config/index.test.ts +++ b/src/components/config/index.test.ts @@ -128,7 +128,7 @@ describe('updateConfig', () => { try { // act await updateConfig({ probes: [] }) - } catch (error) { + } catch (error: unknown) { errorMessage = error.message } diff --git a/src/components/config/parse-har.ts b/src/components/config/parse-har.ts index adbae7134..616a0104f 100644 --- a/src/components/config/parse-har.ts +++ b/src/components/config/parse-har.ts @@ -78,7 +78,7 @@ export const parseHarFile = (fileContents: string): Config => { } return harConfig - } catch (error) { + } catch (error: unknown) { if (error.name === 'SyntaxError') { throw new Error('Har file is in invalid JSON format!') } diff --git a/src/components/config/parse-postman.ts b/src/components/config/parse-postman.ts index 6fd6209a1..38c6d4499 100644 --- a/src/components/config/parse-postman.ts +++ b/src/components/config/parse-postman.ts @@ -132,7 +132,7 @@ export const parseConfigFromPostman = (configString: string): Config => { const probes = generateProbesFromConfig(config, version) return { probes } - } catch (error) { + } catch (error: unknown) { if (error.name === 'SyntaxError') { throw new Error('Your Postman file contains an invalid JSON format!') } diff --git a/src/components/config/parse.ts b/src/components/config/parse.ts index dc491d876..2213d286c 100644 --- a/src/components/config/parse.ts +++ b/src/components/config/parse.ts @@ -87,7 +87,7 @@ export const parseConfig = async ( } return JSON.parse(configString) - } catch (error) { + } catch (error: unknown) { if (error.code === 'ENOENT' && error.path === source) { throw new Error(`Configuration file not found: ${source}.`) } diff --git a/src/components/config/validation/validator/probe.ts b/src/components/config/validation/validator/probe.ts index 0222c6430..ed71cb9b9 100644 --- a/src/components/config/validation/validator/probe.ts +++ b/src/components/config/validation/validator/probe.ts @@ -321,7 +321,7 @@ export async function validateProbes(probes: Probe[]): Promise { return await schema.validateAsync(probes, { stripUnknown: true, }) - } catch (error) { + } catch (error: unknown) { throw new Error(`Monika configuration is invalid. Probe: ${error?.message}`) } } diff --git a/src/components/logger/history.ts b/src/components/logger/history.ts index d466dc744..2043b5c41 100644 --- a/src/components/logger/history.ts +++ b/src/components/logger/history.ts @@ -155,7 +155,7 @@ export async function openLogfile(): Promise { setDatabase(db) await migrate() - } catch (error) { + } catch (error: unknown) { log.error("Warning: Can't open logfile. " + error.message) } } @@ -486,7 +486,7 @@ export async function saveProbeRequestLog({ ]) ) ) - } catch (error) { + } catch (error: unknown) { log.error("Error: Can't insert data into monika-log.db. " + error.message) } } @@ -530,7 +530,7 @@ export async function saveNotificationLog( notification.id, notification.type, ]) - } catch (error) { + } catch (error: unknown) { log.error("Error: Can't insert data into monika-log.db. " + error.message) } } diff --git a/src/components/probe/prober/icmp/request.ts b/src/components/probe/prober/icmp/request.ts index 0200e6eeb..ad3ad2c51 100644 --- a/src/components/probe/prober/icmp/request.ts +++ b/src/components/probe/prober/icmp/request.ts @@ -73,7 +73,7 @@ export async function icmpRequest( icmpResp.output = resp.output return processICMPRequestResult(icmpResp) - } catch (error) { + } catch (error: unknown) { console.error('icmp got error:', error) baseResponse.data = '' baseResponse.error = error diff --git a/src/components/probe/prober/mongo/request.ts b/src/components/probe/prober/mongo/request.ts index 968d18ba0..fa0bf7686 100644 --- a/src/components/probe/prober/mongo/request.ts +++ b/src/components/probe/prober/mongo/request.ts @@ -140,7 +140,7 @@ async function sendMongoRequest(params: MongoRequest): Promise { result.isAlive = true result.message = `${host}:${port} PONGED` } - } catch (error) { + } catch (error: unknown) { result.message = error } finally { if (client) { diff --git a/src/components/probe/prober/postgres/request.ts b/src/components/probe/prober/postgres/request.ts index c0a2640b9..be7ca68bc 100644 --- a/src/components/probe/prober/postgres/request.ts +++ b/src/components/probe/prober/postgres/request.ts @@ -98,7 +98,7 @@ async function sendPsqlRequest(params: PostgresParam): Promise { await client.query('SELECT NOW()') result.message = 'postgres ok' result.isAlive = true - } catch (error) { + } catch (error: unknown) { result.message = error.message } finally { if (client !== false) { diff --git a/src/components/probe/prober/redis/request.ts b/src/components/probe/prober/redis/request.ts index 58605ccf6..4ee5229b4 100644 --- a/src/components/probe/prober/redis/request.ts +++ b/src/components/probe/prober/redis/request.ts @@ -110,7 +110,7 @@ async function sendRedisRequest(params: Redis): Promise { result.isAlive = true result.message = `redis PONGED` } - } catch (error) { + } catch (error: unknown) { result.message = error } diff --git a/src/components/probe/prober/socket/request.ts b/src/components/probe/prober/socket/request.ts index 4848fd915..e94ff39b6 100644 --- a/src/components/probe/prober/socket/request.ts +++ b/src/components/probe/prober/socket/request.ts @@ -82,7 +82,7 @@ async function tcpCheck(tcpRequest: TCPRequest): Promise { status: 'UP', message: '', } - } catch (error) { + } catch (error: unknown) { return { duration: 0, responseData: null, diff --git a/src/events/subscribers/probe.ts b/src/events/subscribers/probe.ts index 458fea70f..3b5826ba6 100644 --- a/src/events/subscribers/probe.ts +++ b/src/events/subscribers/probe.ts @@ -58,7 +58,7 @@ eventEmitter.on( log.info( `Atlassian status page (${type}). id: ${incidentID}, probeID: ${probeID}, url: ${url}` ) - } catch (error) { + } catch (error: unknown) { log.error( `Atlassian status page (Error). probeID: ${probeID}, url: ${url}, probeState: ${probeState} error: ${error}` ) diff --git a/src/jobs/summary-notification.ts b/src/jobs/summary-notification.ts index 256689ff4..bba853693 100644 --- a/src/jobs/summary-notification.ts +++ b/src/jobs/summary-notification.ts @@ -123,7 +123,7 @@ ${tweetMessage} if (checkIs24HourHasPassed()) { resetlogs() } - } catch (error) { + } catch (error: unknown) { log.error(`Summary notification: ${error.message}`) } } @@ -144,7 +144,7 @@ function readPidFile(): PidObject { let data = '' try { data = fs.readFileSync('monika.pid', 'utf8') - } catch (error) { + } catch (error: unknown) { if (error.code === 'ENOENT') { log.info( 'Could not find the file: monika.pid. Monika is probably not running or ran from a diffent directory' @@ -245,7 +245,7 @@ export async function printSummary(cliConfig: IConfig): Promise { App version : ${cliConfig.userAgent} `) - } catch (error) { + } catch (error: unknown) { log.error(`Summary notification: ${error.message}`) } } diff --git a/src/plugins/metrics/prometheus/publisher.ts b/src/plugins/metrics/prometheus/publisher.ts index fc71c985f..3c1cf1bbb 100644 --- a/src/plugins/metrics/prometheus/publisher.ts +++ b/src/plugins/metrics/prometheus/publisher.ts @@ -45,7 +45,7 @@ export function startPrometheusMetricsServer(port: number): void { const prometheusMetrics = await register.metrics() res.status(200).end(prometheusMetrics) - } catch (error) { + } catch (error: unknown) { res.status(500).json({ message: error.message }) } }) diff --git a/src/plugins/updater/index.ts b/src/plugins/updater/index.ts index ff94da10f..466ae5ab5 100644 --- a/src/plugins/updater/index.ts +++ b/src/plugins/updater/index.ts @@ -156,7 +156,7 @@ async function updateMonika(config: IConfig, remoteVersion: string) { `npm install -g @hyperjumptech/monika@${remoteVersion}`, true ) - } catch (error) { + } catch (error: unknown) { log.error(`Updater: npm install error, ${error}`) } @@ -247,7 +247,7 @@ async function moveExtractedFiles(config: IConfig, source: string) { ) { await chmod(destFile, 0o755) } - } catch (error) { + } catch (error: unknown) { log.error(`Updater: move files error ${error}`) } } diff --git a/src/plugins/visualization/atlassian-status-page/index.ts b/src/plugins/visualization/atlassian-status-page/index.ts index fa4d91488..c07cdcbda 100644 --- a/src/plugins/visualization/atlassian-status-page/index.ts +++ b/src/plugins/visualization/atlassian-status-page/index.ts @@ -133,7 +133,7 @@ export class AtlassianStatusPageAPI { await insertIncidentToDatabase({ incidentID, probeID, status, url }) return incidentID - } catch (error) { + } catch (error: unknown) { throw new Error( `${error?.message}${ error?.data ? `. ${error?.response?.data?.message}` : '' @@ -169,7 +169,7 @@ export class AtlassianStatusPageAPI { data, this.axiosConfig ) - } catch (error) { + } catch (error: unknown) { throw new Error( `${error?.message}${ error?.data ? `. ${error?.response?.data?.message}` : '' From 4a16b1420e3d4d7ece0e2f4a9f4a23c4b3ac75ba Mon Sep 17 00:00:00 2001 From: Mochamad Noor Syamsu Date: Fri, 1 Dec 2023 22:21:49 +0700 Subject: [PATCH 9/9] fix build from unknown type --- src/components/config/index.test.ts | 3 ++- src/components/config/index.ts | 2 +- src/components/config/parse-har.ts | 6 +++-- src/components/config/parse-postman.ts | 8 +++--- src/components/config/parse.ts | 17 ++++++------ .../config/validation/validator/probe.ts | 5 +++- src/components/logger/history.ts | 11 +++++--- src/components/probe/prober/icmp/request.ts | 3 ++- .../probe/prober/mariadb/request.ts | 2 +- src/components/probe/prober/mongo/request.ts | 3 ++- .../probe/prober/postgres/request.ts | 3 ++- src/components/probe/prober/redis/request.ts | 3 ++- src/components/probe/prober/socket/request.ts | 3 ++- src/components/tls-checker/index.test.ts | 2 +- src/jobs/summary-notification.ts | 26 ++++++------------- src/plugins/metrics/prometheus/publisher.ts | 3 ++- .../atlassian-status-page/index.ts | 16 ++++++++---- src/symon/index.test.ts | 2 +- src/utils/read-file.ts | 18 +++++++++++++ 19 files changed, 84 insertions(+), 52 deletions(-) create mode 100644 src/utils/read-file.ts diff --git a/src/components/config/index.test.ts b/src/components/config/index.test.ts index 3c1a7d447..592e45dec 100644 --- a/src/components/config/index.test.ts +++ b/src/components/config/index.test.ts @@ -31,6 +31,7 @@ import { md5Hash } from '../../utils/hash' import { getEventEmitter } from '../../utils/events' import type { MonikaFlags } from '../../flag' import { validateProbes } from './validation' +import { getErrorMessage } from '../../utils/catch-error-handler' describe('getConfig', () => { beforeEach(() => { @@ -129,7 +130,7 @@ describe('updateConfig', () => { // act await updateConfig({ probes: [] }) } catch (error: unknown) { - errorMessage = error.message + errorMessage = getErrorMessage(error) } // assert diff --git a/src/components/config/index.ts b/src/components/config/index.ts index 6d80c58be..385f0576b 100644 --- a/src/components/config/index.ts +++ b/src/components/config/index.ts @@ -48,7 +48,7 @@ import { mergeConfigs, } from './get' import { getProbes, setProbes } from './probe' -import { getErrorMessage } from 'src/utils/catch-error-handler' +import { getErrorMessage } from '../../utils/catch-error-handler' type ScheduleRemoteConfigFetcherParams = { configType: ConfigType diff --git a/src/components/config/parse-har.ts b/src/components/config/parse-har.ts index 616a0104f..29fc6d78e 100644 --- a/src/components/config/parse-har.ts +++ b/src/components/config/parse-har.ts @@ -79,10 +79,12 @@ export const parseHarFile = (fileContents: string): Config => { return harConfig } catch (error: unknown) { - if (error.name === 'SyntaxError') { + const parsingError = + error instanceof Error ? error : new Error(`Parsing failed: ${error}.`) + if (parsingError.name === 'SyntaxError') { throw new Error('Har file is in invalid JSON format!') } - throw new Error(error.message) + throw new Error(parsingError.message) } } diff --git a/src/components/config/parse-postman.ts b/src/components/config/parse-postman.ts index 38c6d4499..96c1425c6 100644 --- a/src/components/config/parse-postman.ts +++ b/src/components/config/parse-postman.ts @@ -133,16 +133,18 @@ export const parseConfigFromPostman = (configString: string): Config => { return { probes } } catch (error: unknown) { - if (error.name === 'SyntaxError') { + const parsingError = + error instanceof Error ? error : new Error(`Parsing failed: ${error}`) + if (parsingError.name === 'SyntaxError') { throw new Error('Your Postman file contains an invalid JSON format!') } - if (error.message === 'UnsupportedVersion') { + if (parsingError.message === 'UnsupportedVersion') { throw new Error( 'Your Postman collection version is not supported. Please use v2.0 or v2.1!' ) } - throw new Error(error.message) + throw new Error(parsingError.message) } } diff --git a/src/components/config/parse.ts b/src/components/config/parse.ts index 2213d286c..8dc07af94 100644 --- a/src/components/config/parse.ts +++ b/src/components/config/parse.ts @@ -23,7 +23,6 @@ **********************************************************************************/ import { Config } from '../../interfaces/config' -import { readFileSync } from 'fs' import type { MonikaFlags } from '../../flag' import { parseConfigFromPostman } from './parse-postman' import { parseConfigFromSitemap } from './parse-sitemap' @@ -34,6 +33,7 @@ import yml from 'js-yaml' import parseInsomnia from './parse-insomnia' import isUrl from 'is-url' import { fetchConfig } from './fetch' +import { readFile } from '../../utils/read-file' function sleep(ms: number): Promise { // eslint-disable-next-line no-promise-executor-return @@ -48,7 +48,7 @@ export const parseConfig = async ( try { let configString = isUrl(source) ? await fetchConfig(source) - : readFileSync(source, 'utf-8') + : await readFile(source, 'utf8') if (configString.length === 0) { if (isUrl(source)) @@ -60,7 +60,8 @@ export const parseConfig = async ( let tries = 10 // tries multiple times to load the file while (configString.length === 0 && tries > 0) { sleep(700) - configString = readFileSync(source, 'utf-8') + // eslint-disable-next-line no-await-in-loop + configString = await readFile(source, 'utf8') if (configString.length > 0) { break } @@ -88,14 +89,12 @@ export const parseConfig = async ( return JSON.parse(configString) } catch (error: unknown) { - if (error.code === 'ENOENT' && error.path === source) { - throw new Error(`Configuration file not found: ${source}.`) - } - - if (error.name === 'SyntaxError') { + const parsingError = + error instanceof Error ? error : new Error(String(error)) + if (parsingError.name === 'SyntaxError') { throw new Error('JSON configuration file is in invalid JSON format!') } - throw new Error(error.message) + throw new Error(parsingError.message) } } diff --git a/src/components/config/validation/validator/probe.ts b/src/components/config/validation/validator/probe.ts index ed71cb9b9..01276f63c 100644 --- a/src/components/config/validation/validator/probe.ts +++ b/src/components/config/validation/validator/probe.ts @@ -36,6 +36,7 @@ import { DEFAULT_INTERVAL, DEFAULT_RECOVERY_THRESHOLD, } from './default-values' +import { getErrorMessage } from '../../../../utils/catch-error-handler' const ALERT_QUERY = 'status-not-2xx' const RESPONSE_TIME_PREFIX = 'response-time-greater-than-' @@ -322,7 +323,9 @@ export async function validateProbes(probes: Probe[]): Promise { stripUnknown: true, }) } catch (error: unknown) { - throw new Error(`Monika configuration is invalid. Probe: ${error?.message}`) + throw new Error( + `Monika configuration is invalid. Probe: ${getErrorMessage(error)}` + ) } } diff --git a/src/components/logger/history.ts b/src/components/logger/history.ts index 2043b5c41..97f5174c3 100644 --- a/src/components/logger/history.ts +++ b/src/components/logger/history.ts @@ -31,6 +31,7 @@ import { Probe } from '../../interfaces/probe' import type { Notification } from '@hyperjumptech/monika-notification' import { log } from '../../utils/pino' import { getConfig } from '../config' +import { getErrorMessage } from '../../utils/catch-error-handler' const sqlite3 = SQLite3.verbose() const dbPath = path.resolve(process.cwd(), 'monika-logs.db') @@ -156,7 +157,7 @@ export async function openLogfile(): Promise { await migrate() } catch (error: unknown) { - log.error("Warning: Can't open logfile. " + error.message) + log.error("Warning: Can't open logfile. " + getErrorMessage(error)) } } @@ -487,7 +488,9 @@ export async function saveProbeRequestLog({ ) ) } catch (error: unknown) { - log.error("Error: Can't insert data into monika-log.db. " + error.message) + log.error( + "Error: Can't insert data into monika-log.db. " + getErrorMessage(error) + ) } } @@ -531,7 +534,9 @@ export async function saveNotificationLog( notification.type, ]) } catch (error: unknown) { - log.error("Error: Can't insert data into monika-log.db. " + error.message) + log.error( + "Error: Can't insert data into monika-log.db. " + getErrorMessage(error) + ) } } diff --git a/src/components/probe/prober/icmp/request.ts b/src/components/probe/prober/icmp/request.ts index ad3ad2c51..41891d982 100644 --- a/src/components/probe/prober/icmp/request.ts +++ b/src/components/probe/prober/icmp/request.ts @@ -27,6 +27,7 @@ import { ProbeRequestResponse, probeRequestResult, } from '../../../../interfaces/request' +import { getErrorMessage } from '../../../../utils/catch-error-handler' type icmpParams = { host: string // target to ping @@ -76,7 +77,7 @@ export async function icmpRequest( } catch (error: unknown) { console.error('icmp got error:', error) baseResponse.data = '' - baseResponse.error = error + baseResponse.error = getErrorMessage(error) } return baseResponse diff --git a/src/components/probe/prober/mariadb/request.ts b/src/components/probe/prober/mariadb/request.ts index fafc1d266..95ef6559b 100644 --- a/src/components/probe/prober/mariadb/request.ts +++ b/src/components/probe/prober/mariadb/request.ts @@ -22,7 +22,7 @@ * SOFTWARE. * **********************************************************************************/ -import { getErrorMessage } from 'src/utils/catch-error-handler' +import { getErrorMessage } from '../../../../utils/catch-error-handler' import type { ProbeRequestResponse } from '../../../../interfaces/request' import { probeRequestResult } from '../../../../interfaces/request' import { differenceInMilliseconds } from 'date-fns' diff --git a/src/components/probe/prober/mongo/request.ts b/src/components/probe/prober/mongo/request.ts index fa0bf7686..c9fd77b44 100644 --- a/src/components/probe/prober/mongo/request.ts +++ b/src/components/probe/prober/mongo/request.ts @@ -27,6 +27,7 @@ import * as mongodbURI from 'mongodb-uri' import { probeRequestResult } from '../../../../interfaces/request' import type { ProbeRequestResponse } from '../../../../interfaces/request' import { differenceInMilliseconds } from 'date-fns' +import { getErrorMessage } from '../../../../utils/catch-error-handler' type MongoRequest = { uri?: string // Connection URI @@ -141,7 +142,7 @@ async function sendMongoRequest(params: MongoRequest): Promise { result.message = `${host}:${port} PONGED` } } catch (error: unknown) { - result.message = error + result.message = getErrorMessage(error) } finally { if (client) { await client.close() diff --git a/src/components/probe/prober/postgres/request.ts b/src/components/probe/prober/postgres/request.ts index be7ca68bc..e47aefb84 100644 --- a/src/components/probe/prober/postgres/request.ts +++ b/src/components/probe/prober/postgres/request.ts @@ -26,6 +26,7 @@ import { Pool } from 'pg' import type { ProbeRequestResponse } from '../../../../interfaces/request' import { probeRequestResult } from '../../../../interfaces/request' import { differenceInMilliseconds } from 'date-fns' +import { getErrorMessage } from '../../../../utils/catch-error-handler' export type PostgresParam = { host: string // Host address of the psql db @@ -99,7 +100,7 @@ async function sendPsqlRequest(params: PostgresParam): Promise { result.message = 'postgres ok' result.isAlive = true } catch (error: unknown) { - result.message = error.message + result.message = getErrorMessage(error) } finally { if (client !== false) { // release if connect was previously successful. diff --git a/src/components/probe/prober/redis/request.ts b/src/components/probe/prober/redis/request.ts index 4ee5229b4..3bbd18317 100644 --- a/src/components/probe/prober/redis/request.ts +++ b/src/components/probe/prober/redis/request.ts @@ -27,6 +27,7 @@ import type { ProbeRequestResponse } from '../../../../interfaces/request' import { differenceInMilliseconds } from 'date-fns' import type { Redis } from '../../../../interfaces/probe' import { probeRequestResult } from '../../../../interfaces/request' +import { getErrorMessage } from '../../../../utils/catch-error-handler' type RedisResult = { isAlive: boolean // If redis responds to PING/commands @@ -111,7 +112,7 @@ async function sendRedisRequest(params: Redis): Promise { result.message = `redis PONGED` } } catch (error: unknown) { - result.message = error + result.message = getErrorMessage(error) } return result diff --git a/src/components/probe/prober/socket/request.ts b/src/components/probe/prober/socket/request.ts index e94ff39b6..9dfc0bf2d 100644 --- a/src/components/probe/prober/socket/request.ts +++ b/src/components/probe/prober/socket/request.ts @@ -26,6 +26,7 @@ import net from 'net' import { differenceInMilliseconds } from 'date-fns' import { probeRequestResult } from '../../../../interfaces/request' import type { ProbeRequestResponse } from '../../../../interfaces/request' +import { getErrorMessage } from '../../../../utils/catch-error-handler' type TCPRequest = { host: string @@ -87,7 +88,7 @@ async function tcpCheck(tcpRequest: TCPRequest): Promise { duration: 0, responseData: null, status: 'DOWN', - message: error?.message, + message: getErrorMessage(error), } } } diff --git a/src/components/tls-checker/index.test.ts b/src/components/tls-checker/index.test.ts index 3159e1b4a..7bd64b8a8 100644 --- a/src/components/tls-checker/index.test.ts +++ b/src/components/tls-checker/index.test.ts @@ -24,7 +24,7 @@ import { expect } from '@oclif/test' import { checkTLS } from '../tls-checker' -import { getErrorMessage } from 'src/utils/catch-error-handler' +import { getErrorMessage } from '../../utils/catch-error-handler' describe('TLS Checker', () => { describe('fail attempt', () => { diff --git a/src/jobs/summary-notification.ts b/src/jobs/summary-notification.ts index bba853693..757fc43d3 100644 --- a/src/jobs/summary-notification.ts +++ b/src/jobs/summary-notification.ts @@ -50,6 +50,8 @@ import { Config } from '../interfaces/config' import { getEventEmitter } from '../utils/events' import type { Notification } from '@hyperjumptech/monika-notification' import type { Probe } from '../interfaces/probe' +import { getErrorMessage } from '../utils/catch-error-handler' +import { readFile } from '../utils/read-file' const eventEmitter = getEventEmitter() type TweetMessage = { @@ -124,7 +126,7 @@ ${tweetMessage} resetlogs() } } catch (error: unknown) { - log.error(`Summary notification: ${error.message}`) + log.error(`Summary notification: ${getErrorMessage(error)}`) } } @@ -140,21 +142,9 @@ interface PidObject { * readsPidFile reads a local monika.pid file and returns the information in it * @returns {object} PidObject is returned */ -function readPidFile(): PidObject { - let data = '' - try { - data = fs.readFileSync('monika.pid', 'utf8') - } catch (error: unknown) { - if (error.code === 'ENOENT') { - log.info( - 'Could not find the file: monika.pid. Monika is probably not running or ran from a diffent directory' - ) - } - - throw error - } - - const json = JSON.parse(data) +async function readPidFile(): Promise { + const fileContent = await readFile('monika.pid', 'utf8') + const json = JSON.parse(fileContent) return { monikaPid: json.monikaPid, monikaConfigFile: json.monikaConfigFile, @@ -222,7 +212,7 @@ function getDaysHours(startTime: Date): string { */ export async function printSummary(cliConfig: IConfig): Promise { try { - const pidObject = readPidFile() + const pidObject = await readPidFile() const summary = await getSummary() const uptime = getDaysHours(pidObject.monikaStartTime) @@ -246,7 +236,7 @@ export async function printSummary(cliConfig: IConfig): Promise { `) } catch (error: unknown) { - log.error(`Summary notification: ${error.message}`) + log.error(`Summary notification: ${getErrorMessage(error)}`) } } diff --git a/src/plugins/metrics/prometheus/publisher.ts b/src/plugins/metrics/prometheus/publisher.ts index 3c1cf1bbb..59ab5bcd5 100644 --- a/src/plugins/metrics/prometheus/publisher.ts +++ b/src/plugins/metrics/prometheus/publisher.ts @@ -26,6 +26,7 @@ import express, { Request, Response, NextFunction } from 'express' import helmet from 'helmet' import { register } from 'prom-client' import { log } from '../../../utils/pino' +import { getErrorMessage } from '../../../utils/catch-error-handler' export function startPrometheusMetricsServer(port: number): void { const app = express() @@ -46,7 +47,7 @@ export function startPrometheusMetricsServer(port: number): void { res.status(200).end(prometheusMetrics) } catch (error: unknown) { - res.status(500).json({ message: error.message }) + res.status(500).json({ message: getErrorMessage(error) }) } }) diff --git a/src/plugins/visualization/atlassian-status-page/index.ts b/src/plugins/visualization/atlassian-status-page/index.ts index c07cdcbda..64f0f21d7 100644 --- a/src/plugins/visualization/atlassian-status-page/index.ts +++ b/src/plugins/visualization/atlassian-status-page/index.ts @@ -22,7 +22,7 @@ * SOFTWARE. * **********************************************************************************/ -import axios from 'axios' +import axios, { AxiosError } from 'axios' import http from 'http' import https from 'https' import Joi from 'joi' @@ -134,9 +134,12 @@ export class AtlassianStatusPageAPI { return incidentID } catch (error: unknown) { + const axiosError = error instanceof AxiosError ? error : new AxiosError() throw new Error( - `${error?.message}${ - error?.data ? `. ${error?.response?.data?.message}` : '' + `${axiosError?.message}${ + axiosError?.response?.data + ? `. ${axiosError?.response?.data?.message}` + : '' }` ) } @@ -170,9 +173,12 @@ export class AtlassianStatusPageAPI { this.axiosConfig ) } catch (error: unknown) { + const axiosError = error instanceof AxiosError ? error : new AxiosError() throw new Error( - `${error?.message}${ - error?.data ? `. ${error?.response?.data?.message}` : '' + `${axiosError?.message}${ + axiosError?.response?.data + ? `. ${axiosError?.response?.data?.message}` + : '' }` ) } diff --git a/src/symon/index.test.ts b/src/symon/index.test.ts index acf997635..e243d0bb4 100644 --- a/src/symon/index.test.ts +++ b/src/symon/index.test.ts @@ -37,7 +37,7 @@ import { validateProbes } from '../components/config/validation' import events from '../events' import { md5Hash } from '../utils/hash' import { getEventEmitter } from '../utils/events' -import { getErrorMessage } from 'src/utils/catch-error-handler' +import { getErrorMessage } from '../utils/catch-error-handler' const config: Config = { version: 'asdfg123', diff --git a/src/utils/read-file.ts b/src/utils/read-file.ts new file mode 100644 index 000000000..633cfc958 --- /dev/null +++ b/src/utils/read-file.ts @@ -0,0 +1,18 @@ +import { log } from './pino' +import fs from 'fs' + +// Alternative of fs.readFileSync() API with type safety error NodeJS.ErrnoException +export async function readFile(path: string, encoding: string) { + return new Promise((resolve, reject) => { + fs.readFile(path, encoding, (error, result) => { + if (error && error?.code === 'ENOENT') { + log.info( + `Could not find the file: ${path}. Monika is probably not running or ran from a diffent directory` + ) + reject(error) + } else { + resolve(result) + } + }) + }) +}