resolve remaining TS errors
This commit is contained in:
1 parent
a0ea50d745
commit
f79a87f98a
3 files changed
+280
-123
No files matched your search
@@ -145,7 +145,22 @@ export const initializeServices = async ({
|
||||
const teamsRepository = new MongoTeamsRepository();
|
||||
const maintenanceWindowsRepository = new MongoMaintenanceWindowsRepository();
|
||||
|
||||
const networkService = new NetworkService(axios, got, https, jmespath, GameDig, ping, logger, Docker, net, settingsService, grpc, protoLoader);
|
||||
const networkService = new NetworkService(
|
||||
axios,
|
||||
got,
|
||||
https,
|
||||
jmespath,
|
||||
GameDig as unknown as {
|
||||
query: (options: { type: string; host: string; port?: number }) => Promise<{ ping?: number } & { [key: string]: unknown }>;
|
||||
},
|
||||
ping,
|
||||
logger,
|
||||
Docker,
|
||||
net,
|
||||
settingsService,
|
||||
grpc,
|
||||
protoLoader
|
||||
);
|
||||
const emailService = new EmailService(settingsService, fs, path, compile, mjml2html, nodemailer, logger);
|
||||
|
||||
const notificationMessageBuilder = new NotificationMessageBuilder();
|
||||
|
||||
@@ -7,6 +7,10 @@ import type {
|
||||
PageSpeedStatusPayload,
|
||||
HttpStatusPayload,
|
||||
HardwareStatusPayload,
|
||||
PingStatusPayload,
|
||||
DockerStatusPayload,
|
||||
PortStatusPayload,
|
||||
GameStatusPayload,
|
||||
} from "@/types/index.js";
|
||||
import type { AxiosStatic } from "axios";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
@@ -34,8 +38,25 @@ interface BuildStatusResponseArgs<T> {
|
||||
|
||||
export interface INetworkService {
|
||||
readonly serviceName: string;
|
||||
requestStatus(monitor: Monitor): Promise<MonitorStatusResponse>;
|
||||
requestWebhook(type: string, url: string, body: any): Promise<{ type: string; status: boolean; code: number; message: string; payload?: unknown }>;
|
||||
requestStatus(
|
||||
monitor: Monitor
|
||||
): Promise<
|
||||
MonitorStatusResponse<
|
||||
| PingStatusPayload
|
||||
| HttpStatusPayload
|
||||
| PageSpeedStatusPayload
|
||||
| HardwareStatusPayload
|
||||
| DockerStatusPayload
|
||||
| PortStatusPayload
|
||||
| GameStatusPayload
|
||||
| GrpcStatusPayload
|
||||
>
|
||||
>;
|
||||
requestWebhook(
|
||||
type: string,
|
||||
url: string,
|
||||
body: unknown
|
||||
): Promise<{ type: string; status: boolean; code: number; message: string; payload?: unknown }>;
|
||||
requestPagerDuty(args: { message: string; routingKey: string; monitorUrl: string }): Promise<boolean>;
|
||||
requestMatrix(args: { homeserverUrl: string; accessToken: string; roomId: string; message: string }): Promise<{
|
||||
status: boolean;
|
||||
@@ -62,16 +83,16 @@ class NetworkService implements INetworkService {
|
||||
|
||||
private axios: AxiosStatic;
|
||||
private got: Got;
|
||||
private https: any;
|
||||
private jmespath: any;
|
||||
private GameDig: any;
|
||||
private ping: any;
|
||||
private https: typeof import("https");
|
||||
private jmespath: { search: (data: unknown, expression: string) => unknown };
|
||||
private GameDig: { query: (options: { type: string; host: string; port?: number }) => Promise<{ ping?: number } & { [key: string]: unknown }> };
|
||||
private ping: typeof import("ping");
|
||||
private logger: ILogger;
|
||||
private Docker: any;
|
||||
private net: any;
|
||||
private Docker: typeof import("dockerode");
|
||||
private net: typeof import("net");
|
||||
private settingsService: ISettingsService;
|
||||
private grpc: any;
|
||||
private protoLoader: any;
|
||||
private grpc: typeof import("@grpc/grpc-js");
|
||||
private protoLoader: typeof import("@grpc/proto-loader");
|
||||
|
||||
private buildStatusResponse = <T>({
|
||||
monitor,
|
||||
@@ -106,7 +127,7 @@ class NetworkService implements INetworkService {
|
||||
statusResponse.responseTime = error.timings?.phases?.total ?? 0;
|
||||
statusResponse.timings = error.timings;
|
||||
}
|
||||
return { ...statusResponse, ...(overrides ?? {}) };
|
||||
return { ...statusResponse, ...(overrides ?? {}) } as MonitorStatusResponse<T>;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -124,22 +145,22 @@ class NetworkService implements INetworkService {
|
||||
expectedValue,
|
||||
extracted,
|
||||
...(overrides ?? {}),
|
||||
};
|
||||
} as MonitorStatusResponse<T>;
|
||||
};
|
||||
|
||||
constructor(
|
||||
axios: AxiosStatic,
|
||||
got: Got,
|
||||
https: any,
|
||||
jmespath: any,
|
||||
GameDig: any,
|
||||
ping: any,
|
||||
https: typeof import("https"),
|
||||
jmespath: { search: (data: unknown, expression: string) => unknown },
|
||||
GameDig: { query: (options: { type: string; host: string; port?: number }) => Promise<{ ping?: number } & { [key: string]: unknown }> },
|
||||
ping: typeof import("ping"),
|
||||
logger: ILogger,
|
||||
Docker: any,
|
||||
net: any,
|
||||
Docker: typeof import("dockerode"),
|
||||
net: typeof import("net"),
|
||||
settingsService: ISettingsService,
|
||||
grpc: any,
|
||||
protoLoader: any
|
||||
grpc: typeof import("@grpc/grpc-js"),
|
||||
protoLoader: typeof import("@grpc/proto-loader")
|
||||
) {
|
||||
this.TYPE_PING = "ping";
|
||||
this.TYPE_HTTP = "http";
|
||||
@@ -193,7 +214,20 @@ class NetworkService implements INetworkService {
|
||||
}
|
||||
|
||||
// Main entry point
|
||||
async requestStatus(monitor: Monitor): Promise<MonitorStatusResponse> {
|
||||
async requestStatus(
|
||||
monitor: Monitor
|
||||
): Promise<
|
||||
MonitorStatusResponse<
|
||||
| PingStatusPayload
|
||||
| HttpStatusPayload
|
||||
| PageSpeedStatusPayload
|
||||
| HardwareStatusPayload
|
||||
| DockerStatusPayload
|
||||
| PortStatusPayload
|
||||
| GameStatusPayload
|
||||
| GrpcStatusPayload
|
||||
>
|
||||
> {
|
||||
const type = monitor?.type || "unknown";
|
||||
switch (type) {
|
||||
case this.TYPE_PING:
|
||||
@@ -217,7 +251,7 @@ class NetworkService implements INetworkService {
|
||||
}
|
||||
}
|
||||
|
||||
private async requestPing(monitor: Monitor): Promise<MonitorStatusResponse> {
|
||||
private async requestPing(monitor: Monitor): Promise<MonitorStatusResponse<PingStatusPayload>> {
|
||||
try {
|
||||
if (!monitor?.url) {
|
||||
throw new Error("Monitor URL is required");
|
||||
@@ -237,30 +271,27 @@ class NetworkService implements INetworkService {
|
||||
throw new Error("Ping failed - no result returned");
|
||||
}
|
||||
|
||||
const pingResponse = this.buildStatusResponse({
|
||||
const pingResponse = this.buildStatusResponse<PingStatusPayload>({
|
||||
monitor,
|
||||
payload: response,
|
||||
payload: response as PingStatusPayload,
|
||||
overrides: {
|
||||
status: (response as { alive?: boolean })?.alive ?? false,
|
||||
code: 200,
|
||||
message: "Success",
|
||||
responseTime: (response as { time?: number })?.time ?? 0,
|
||||
payload: response,
|
||||
},
|
||||
payload: response as PingStatusPayload,
|
||||
} as MonitorStatusResponseOverrides<PingStatusPayload>,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
pingResponse.status = false;
|
||||
pingResponse.code = this.PING_ERROR;
|
||||
pingResponse.message = "Ping failed";
|
||||
return pingResponse;
|
||||
}
|
||||
|
||||
return pingResponse;
|
||||
} catch (err: any) {
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "requestPing";
|
||||
throw err;
|
||||
} catch (err: unknown) {
|
||||
const originalMessage = err instanceof Error ? err.message : String(err);
|
||||
throw new AppError({
|
||||
message: originalMessage || "Error performing ping",
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestPing",
|
||||
details: { url: monitor.url },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +310,7 @@ class NetworkService implements INetworkService {
|
||||
if (!url) {
|
||||
throw new Error("Monitor URL is required");
|
||||
}
|
||||
const config: Record<string, any> = {
|
||||
const config: Record<string, unknown> = {
|
||||
headers: secret ? { Authorization: `Bearer ${secret}` } : undefined,
|
||||
};
|
||||
|
||||
@@ -293,7 +324,7 @@ class NetworkService implements INetworkService {
|
||||
|
||||
const response = await this.got(url, config);
|
||||
|
||||
let payload: any;
|
||||
let payload: T | string | undefined;
|
||||
const contentType = response.headers["content-type"];
|
||||
|
||||
if (contentType && contentType.includes("application/json")) {
|
||||
@@ -381,19 +412,23 @@ class NetworkService implements INetworkService {
|
||||
}
|
||||
}
|
||||
return httpResponse;
|
||||
} catch (err: any) {
|
||||
if (err.name === "HTTPError" || err.name === "RequestError") {
|
||||
httpResponse.code = err?.response?.statusCode || this.NETWORK_ERROR;
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof HTTPError || err instanceof RequestError) {
|
||||
httpResponse.code = err.response?.statusCode || this.NETWORK_ERROR;
|
||||
httpResponse.status = false;
|
||||
httpResponse.message = err?.response?.statusCode || err.message;
|
||||
httpResponse.responseTime = err?.timings?.phases?.total || 0;
|
||||
httpResponse.message = String(err.response?.statusCode) || err.message;
|
||||
httpResponse.responseTime = err.timings?.phases?.total || 0;
|
||||
httpResponse.payload = null;
|
||||
httpResponse.timings = err?.timings || {};
|
||||
httpResponse.timings = err.timings || undefined;
|
||||
return httpResponse;
|
||||
}
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "requestHttp";
|
||||
throw err;
|
||||
const originalMessage = err instanceof Error ? err.message : String(err);
|
||||
throw new AppError({
|
||||
message: originalMessage || "Error performing HTTP request",
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestHttp",
|
||||
details: { url: monitor.url },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,24 +454,32 @@ class NetworkService implements INetworkService {
|
||||
...monitor,
|
||||
url: pageSpeedUrl,
|
||||
});
|
||||
} catch (err: any) {
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "requestPageSpeed";
|
||||
throw err;
|
||||
} catch (err: unknown) {
|
||||
const originalMessage = err instanceof Error ? err.message : String(err);
|
||||
throw new AppError({
|
||||
message: originalMessage || "Error performing PageSpeed request",
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestPageSpeed",
|
||||
details: { url: monitor.url },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async requestHardware(monitor: Monitor): Promise<MonitorStatusResponse<HardwareStatusPayload>> {
|
||||
try {
|
||||
return await this.requestHttp<HardwareStatusPayload>(monitor);
|
||||
} catch (err: any) {
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "requestHardware";
|
||||
throw err;
|
||||
} catch (err: unknown) {
|
||||
const originalMessage = err instanceof Error ? err.message : String(err);
|
||||
throw new AppError({
|
||||
message: originalMessage || "Error performing hardware request",
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestHardware",
|
||||
details: { url: monitor.url },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async requestDocker(monitor: Monitor): Promise<MonitorStatusResponse> {
|
||||
private async requestDocker(monitor: Monitor): Promise<MonitorStatusResponse<DockerStatusPayload>> {
|
||||
try {
|
||||
if (!monitor.url) {
|
||||
throw new Error("Monitor URL is required");
|
||||
@@ -446,7 +489,7 @@ class NetworkService implements INetworkService {
|
||||
socketPath: "/var/run/docker.sock",
|
||||
});
|
||||
|
||||
const dockerResponse = this.buildStatusResponse({
|
||||
const dockerResponse = this.buildStatusResponse<DockerStatusPayload>({
|
||||
monitor,
|
||||
overrides: {
|
||||
status: false,
|
||||
@@ -455,17 +498,17 @@ class NetworkService implements INetworkService {
|
||||
},
|
||||
});
|
||||
|
||||
const containers = await docker.listContainers({ all: true });
|
||||
const containers = await docker.listContainers();
|
||||
|
||||
// Normalize input: strip leading slashes and convert to lowercase for comparison
|
||||
const normalizedInput = monitor.url.replace(/^\/+/, "").toLowerCase();
|
||||
|
||||
// Priority-based matching to avoid ambiguity:
|
||||
// 1. Exact full ID match (64-char)
|
||||
const exactIdMatch = containers.find((c: any) => c.Id.toLowerCase() === normalizedInput);
|
||||
const exactIdMatch = containers.find((c) => c.Id.toLowerCase() === normalizedInput);
|
||||
|
||||
// 2. Exact container name match (case-insensitive)
|
||||
const exactNameMatch = containers.find((c: any) =>
|
||||
const exactNameMatch = containers.find((c) =>
|
||||
c.Names.some((name: string) => {
|
||||
const cleanName = name.replace(/^\/+/, "").toLowerCase();
|
||||
return cleanName === normalizedInput;
|
||||
@@ -473,7 +516,7 @@ class NetworkService implements INetworkService {
|
||||
);
|
||||
|
||||
// 3. Partial ID match (fallback for backwards compatibility)
|
||||
const partialIdMatch = containers.find((c: any) => c.Id.toLowerCase().startsWith(normalizedInput));
|
||||
const partialIdMatch = containers.find((c) => c.Id.toLowerCase().startsWith(normalizedInput));
|
||||
|
||||
// Select container based on priority
|
||||
const targetContainer = exactIdMatch || exactNameMatch || partialIdMatch;
|
||||
@@ -512,9 +555,8 @@ class NetworkService implements INetworkService {
|
||||
}
|
||||
|
||||
const container = docker.getContainer(targetContainer.Id);
|
||||
const { response, responseTime, error }: { response?: any; responseTime?: number; error?: any } = await this.timeRequest(() =>
|
||||
container.inspect()
|
||||
);
|
||||
const { response, responseTime, error }: { response?: { State: { Status: string } } | null; responseTime: number; error: unknown } =
|
||||
await this.timeRequest(() => container.inspect());
|
||||
|
||||
dockerResponse.responseTime = responseTime;
|
||||
dockerResponse.status = response?.State?.Status === "running" ? true : false;
|
||||
@@ -523,20 +565,28 @@ class NetworkService implements INetworkService {
|
||||
|
||||
if (error) {
|
||||
dockerResponse.status = false;
|
||||
dockerResponse.code = error.statusCode || this.NETWORK_ERROR;
|
||||
dockerResponse.message = error.reason || "Failed to fetch Docker container information";
|
||||
dockerResponse.code =
|
||||
(error && typeof error === "object" && "statusCode" in error ? (error as { statusCode?: number }).statusCode : undefined) ||
|
||||
this.NETWORK_ERROR;
|
||||
dockerResponse.message =
|
||||
(error && typeof error === "object" && "reason" in error ? (error as { reason?: string }).reason : undefined) ||
|
||||
"Failed to fetch Docker container information";
|
||||
return dockerResponse;
|
||||
}
|
||||
|
||||
return dockerResponse;
|
||||
} catch (err: any) {
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "requestDocker";
|
||||
throw err;
|
||||
} catch (err: unknown) {
|
||||
const originalMessage = err instanceof Error ? err.message : String(err);
|
||||
throw new AppError({
|
||||
message: originalMessage || "Error performing Docker request",
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestDocker",
|
||||
details: { url: monitor.url },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async requestPort(monitor: Monitor): Promise<MonitorStatusResponse> {
|
||||
private async requestPort(monitor: Monitor): Promise<MonitorStatusResponse<PortStatusPayload>> {
|
||||
try {
|
||||
const { url, port } = monitor;
|
||||
if (!port) {
|
||||
@@ -563,14 +613,14 @@ class NetworkService implements INetworkService {
|
||||
reject(new Error("Connection timeout"));
|
||||
});
|
||||
|
||||
socket.on("error", (err: any) => {
|
||||
socket.on("error", (err: unknown) => {
|
||||
socket.destroy();
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const portResponse = this.buildStatusResponse({
|
||||
const portResponse = this.buildStatusResponse<PortStatusPayload>({
|
||||
monitor,
|
||||
overrides: {
|
||||
code: 200,
|
||||
@@ -588,18 +638,22 @@ class NetworkService implements INetworkService {
|
||||
}
|
||||
|
||||
return portResponse;
|
||||
} catch (error: any) {
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestTCP";
|
||||
throw error;
|
||||
} catch (err: unknown) {
|
||||
const originalMessage = err instanceof Error ? err.message : String(err);
|
||||
throw new AppError({
|
||||
message: originalMessage || "Error performing port check",
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestPort",
|
||||
details: { url: monitor.url, port: monitor.port },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async requestGame(monitor: Monitor): Promise<MonitorStatusResponse> {
|
||||
private async requestGame(monitor: Monitor): Promise<MonitorStatusResponse<GameStatusPayload>> {
|
||||
try {
|
||||
const { url, port, gameId } = monitor;
|
||||
|
||||
const gameResponse = this.buildStatusResponse({
|
||||
const gameResponse = this.buildStatusResponse<GameStatusPayload>({
|
||||
monitor,
|
||||
overrides: {
|
||||
code: 200,
|
||||
@@ -612,13 +666,14 @@ class NetworkService implements INetworkService {
|
||||
type: gameId ?? "unknown",
|
||||
host: url,
|
||||
port: port ?? 0,
|
||||
}).catch((error: any) => {
|
||||
}).catch((error: unknown): undefined => {
|
||||
this.logger.warn({
|
||||
message: error.message,
|
||||
message: error instanceof Error ? error.message : String(error),
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestGame",
|
||||
details: { url, port, gameId },
|
||||
});
|
||||
return undefined;
|
||||
});
|
||||
|
||||
if (!state) {
|
||||
@@ -628,16 +683,20 @@ class NetworkService implements INetworkService {
|
||||
return gameResponse;
|
||||
}
|
||||
|
||||
gameResponse.responseTime = state.ping;
|
||||
gameResponse.payload = state;
|
||||
gameResponse.responseTime = state.ping ?? 0;
|
||||
gameResponse.payload = state as GameStatusPayload;
|
||||
return gameResponse;
|
||||
} catch (error: any) {
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestPing";
|
||||
throw error;
|
||||
} catch (err: unknown) {
|
||||
const originalMessage = err instanceof Error ? err.message : String(err);
|
||||
throw new AppError({
|
||||
message: originalMessage || "Error performing game server check",
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestGame",
|
||||
details: { url: monitor.url, port: monitor.port, gameId: monitor.gameId },
|
||||
});
|
||||
}
|
||||
}
|
||||
private async requestGrpc(monitor: Monitor): Promise<MonitorStatusResponse> {
|
||||
private async requestGrpc(monitor: Monitor): Promise<MonitorStatusResponse<GrpcStatusPayload>> {
|
||||
try {
|
||||
const { url, port, ignoreTlsErrors } = monitor;
|
||||
const grpcServiceName = monitor.grpcServiceName || "";
|
||||
@@ -661,7 +720,21 @@ class NetworkService implements INetworkService {
|
||||
defaults: true,
|
||||
oneofs: true,
|
||||
});
|
||||
const grpcObject = this.grpc.loadPackageDefinition(packageDefinition);
|
||||
const grpcObject = this.grpc.loadPackageDefinition(packageDefinition) as unknown as {
|
||||
grpc: {
|
||||
health: {
|
||||
v1: {
|
||||
Health: new (
|
||||
target: string,
|
||||
credentials: unknown
|
||||
) => {
|
||||
Check: (request: { service: string }, options: { deadline: Date }, callback: (err: unknown, response: unknown) => void) => void;
|
||||
close: () => void;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
const healthService = grpcObject.grpc.health.v1.Health;
|
||||
|
||||
let credentials;
|
||||
@@ -678,7 +751,7 @@ class NetworkService implements INetworkService {
|
||||
const TIMEOUT_MS = 10000;
|
||||
const deadline = new Date(Date.now() + TIMEOUT_MS);
|
||||
|
||||
const grpcResponse = this.buildStatusResponse({
|
||||
const grpcResponse = this.buildStatusResponse<GrpcStatusPayload>({
|
||||
monitor,
|
||||
overrides: {
|
||||
status: false,
|
||||
@@ -689,24 +762,30 @@ class NetworkService implements INetworkService {
|
||||
|
||||
const { response, responseTime, error } = await this.timeRequest<GrpcStatusPayload>(() => {
|
||||
return new Promise<GrpcStatusPayload>((resolve, reject) => {
|
||||
client.Check({ service: grpcServiceName }, { deadline }, (err: any, response: any) => {
|
||||
client.Check({ service: grpcServiceName }, { deadline }, (err: unknown, response: unknown) => {
|
||||
client.close();
|
||||
|
||||
if (err) {
|
||||
const grpcErr = err as { code?: number; details?: string; message?: string };
|
||||
const payload: GrpcStatusPayload = {
|
||||
grpcStatusCode: err.code ?? -1,
|
||||
grpcStatusName: this.getGrpcStatusName(err.code),
|
||||
grpcStatusCode: grpcErr.code ?? -1,
|
||||
grpcStatusName: this.getGrpcStatusName(grpcErr.code ?? -1),
|
||||
serviceName: grpcServiceName,
|
||||
servingStatus: "UNKNOWN",
|
||||
};
|
||||
const grpcError = new AppError({ message: err.details || err.message, service: this.SERVICE_NAME, method: "requestGrpc" });
|
||||
(grpcError as any).grpcPayload = payload;
|
||||
(grpcError as any).grpcCode = err.code;
|
||||
const grpcError = new AppError({
|
||||
message: grpcErr.details || grpcErr.message || "gRPC error",
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestGrpc",
|
||||
}) as AppError & { grpcPayload?: GrpcStatusPayload; grpcCode?: number };
|
||||
grpcError.grpcPayload = payload;
|
||||
grpcError.grpcCode = grpcErr.code;
|
||||
reject(grpcError);
|
||||
return;
|
||||
}
|
||||
|
||||
const servingStatus = response?.status || "UNKNOWN";
|
||||
const resp = response as { status?: string } | undefined;
|
||||
const servingStatus = resp?.status ?? "UNKNOWN";
|
||||
resolve({
|
||||
grpcStatusCode: 0,
|
||||
grpcStatusName: "OK",
|
||||
@@ -718,13 +797,13 @@ class NetworkService implements INetworkService {
|
||||
});
|
||||
|
||||
if (error) {
|
||||
const grpcError = error as any;
|
||||
const payload = grpcError.grpcPayload as GrpcStatusPayload | undefined;
|
||||
const grpcError = error as AppError & { grpcPayload?: GrpcStatusPayload; grpcCode?: number };
|
||||
const payload = grpcError.grpcPayload;
|
||||
grpcResponse.status = false;
|
||||
grpcResponse.code = grpcError.grpcCode ?? this.NETWORK_ERROR;
|
||||
grpcResponse.message = grpcError.message || "gRPC health check failed";
|
||||
grpcResponse.message = grpcError.message ?? "gRPC health check failed";
|
||||
grpcResponse.responseTime = responseTime;
|
||||
grpcResponse.payload = payload || null;
|
||||
grpcResponse.payload = payload ?? null;
|
||||
return grpcResponse;
|
||||
}
|
||||
|
||||
@@ -740,10 +819,14 @@ class NetworkService implements INetworkService {
|
||||
grpcResponse.payload = grpcPayload;
|
||||
|
||||
return grpcResponse;
|
||||
} catch (err: any) {
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "requestGrpc";
|
||||
throw err;
|
||||
} catch (err: unknown) {
|
||||
const originalMessage = err instanceof Error ? err.message : String(err);
|
||||
throw new AppError({
|
||||
message: originalMessage || "Error performing gRPC health check",
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestGrpc",
|
||||
details: { url: monitor.url, port: monitor.port, grpcServiceName: monitor.grpcServiceName },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,7 +865,7 @@ class NetworkService implements INetworkService {
|
||||
}
|
||||
|
||||
// Other network requests unrelated to monitoring:
|
||||
async requestWebhook(type: string, url: string, body: any) {
|
||||
async requestWebhook(type: string, url: string, body: unknown) {
|
||||
try {
|
||||
const response = await this.axios.post(url, body, {
|
||||
headers: {
|
||||
@@ -797,19 +880,29 @@ class NetworkService implements INetworkService {
|
||||
message: `Successfully sent ${type} notification`,
|
||||
payload: response.data,
|
||||
};
|
||||
} catch (error: any) {
|
||||
} catch (err: unknown) {
|
||||
this.logger.warn({
|
||||
message: error.message,
|
||||
message: err instanceof Error ? err.message : String(err),
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestWebhook",
|
||||
});
|
||||
|
||||
if (err && typeof err === "object" && "response" in err) {
|
||||
const axiosError = err as { response?: { status?: number; data?: unknown } };
|
||||
return {
|
||||
type: "webhook",
|
||||
status: false,
|
||||
code: axiosError.response?.status ?? this.NETWORK_ERROR,
|
||||
message: `Failed to send ${type} notification`,
|
||||
payload: axiosError.response?.data,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: "webhook",
|
||||
status: false,
|
||||
code: error.response?.status || this.NETWORK_ERROR,
|
||||
code: this.NETWORK_ERROR,
|
||||
message: `Failed to send ${type} notification`,
|
||||
payload: error.response?.data,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -829,11 +922,17 @@ class NetworkService implements INetworkService {
|
||||
|
||||
if (response?.data?.status !== "success") return false;
|
||||
return true;
|
||||
} catch (error: any) {
|
||||
error.details = error.response?.data;
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestPagerDuty";
|
||||
throw error;
|
||||
} catch (err: unknown) {
|
||||
const originalMessage = err instanceof Error ? err.message : String(err);
|
||||
|
||||
throw new AppError({
|
||||
message: originalMessage || "Error sending PagerDuty notification",
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestPagerDuty",
|
||||
details: {
|
||||
responseData: err && typeof err === "object" && "response" in err ? (err as { response?: { data?: unknown } }).response?.data : undefined,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -867,18 +966,35 @@ class NetworkService implements INetworkService {
|
||||
code: response.status,
|
||||
message: "Successfully sent Matrix notification",
|
||||
};
|
||||
} catch (error: any) {
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof Error) {
|
||||
this.logger.warn({
|
||||
message: err.message,
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestMatrix",
|
||||
});
|
||||
|
||||
if (err && typeof err === "object" && "response" in err) {
|
||||
const axiosError = err as { response?: { status?: number; data?: unknown } };
|
||||
return {
|
||||
status: false,
|
||||
code: axiosError.response?.status || this.NETWORK_ERROR,
|
||||
message: "Failed to send Matrix notification",
|
||||
payload: axiosError.response?.data,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.warn({
|
||||
message: error.message,
|
||||
message: String(err),
|
||||
service: this.SERVICE_NAME,
|
||||
method: "requestMatrix",
|
||||
});
|
||||
|
||||
return {
|
||||
status: false,
|
||||
code: error.response?.status || this.NETWORK_ERROR,
|
||||
code: this.NETWORK_ERROR,
|
||||
message: "Failed to send Matrix notification",
|
||||
payload: error.response?.data,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,12 @@ import type {
|
||||
Check,
|
||||
HardwareStatusPayload,
|
||||
PageSpeedStatusPayload,
|
||||
PingStatusPayload,
|
||||
HttpStatusPayload,
|
||||
DockerStatusPayload,
|
||||
PortStatusPayload,
|
||||
GameStatusPayload,
|
||||
GrpcStatusPayload,
|
||||
CheckSnapshot,
|
||||
MonitorStats,
|
||||
} from "@/types/index.js";
|
||||
@@ -17,7 +23,17 @@ export interface IStatusService {
|
||||
updateRunningStats({ monitor, networkResponse }: { monitor: Monitor; networkResponse: any }): Promise<boolean>;
|
||||
handleIncidentForCheck(check: any, monitor: Monitor, action: any, errorContext?: string): Promise<void>;
|
||||
updateMonitorStatus(
|
||||
statusResponse: MonitorStatusResponse<PageSpeedStatusPayload | HardwareStatusPayload | undefined>,
|
||||
statusResponse: MonitorStatusResponse<
|
||||
| PingStatusPayload
|
||||
| HttpStatusPayload
|
||||
| PageSpeedStatusPayload
|
||||
| HardwareStatusPayload
|
||||
| DockerStatusPayload
|
||||
| PortStatusPayload
|
||||
| GameStatusPayload
|
||||
| GrpcStatusPayload
|
||||
| undefined
|
||||
>,
|
||||
check: Check
|
||||
): Promise<StatusChangeResult>;
|
||||
}
|
||||
@@ -205,7 +221,17 @@ export class StatusService implements IStatusService {
|
||||
};
|
||||
|
||||
updateMonitorStatus = async (
|
||||
statusResponse: MonitorStatusResponse<PageSpeedStatusPayload | HardwareStatusPayload | undefined>,
|
||||
statusResponse: MonitorStatusResponse<
|
||||
| PingStatusPayload
|
||||
| HttpStatusPayload
|
||||
| PageSpeedStatusPayload
|
||||
| HardwareStatusPayload
|
||||
| DockerStatusPayload
|
||||
| PortStatusPayload
|
||||
| GameStatusPayload
|
||||
| GrpcStatusPayload
|
||||
| undefined
|
||||
>,
|
||||
check: Check
|
||||
): Promise<StatusChangeResult> => {
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user