mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-13 02:17:05 +00:00
fix docker error handling
fix websocket routes Add timezone variable in code changed the env.example to suit
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
const WebSocket = require("ws");
|
||||
const url = require("node:url");
|
||||
const { get_current_time } = require("../utils/timezone");
|
||||
|
||||
// Connection registry by api_id
|
||||
const apiIdToSocket = new Map();
|
||||
@@ -49,7 +50,29 @@ function init(server, prismaClient) {
|
||||
wss.handleUpgrade(request, socket, head, (ws) => {
|
||||
ws.on("message", (message) => {
|
||||
// Echo back for Bull Board WebSocket
|
||||
ws.send(message);
|
||||
try {
|
||||
ws.send(message);
|
||||
} catch (err) {
|
||||
// Ignore send errors (connection may be closed)
|
||||
}
|
||||
});
|
||||
|
||||
ws.on("error", (err) => {
|
||||
// Handle WebSocket errors gracefully for Bull Board
|
||||
if (
|
||||
err.code === "WS_ERR_INVALID_CLOSE_CODE" ||
|
||||
err.code === "ECONNRESET" ||
|
||||
err.code === "EPIPE"
|
||||
) {
|
||||
// These are expected errors, just log quietly
|
||||
console.log("[bullboard-ws] connection error:", err.code);
|
||||
} else {
|
||||
console.error("[bullboard-ws] error:", err.message || err);
|
||||
}
|
||||
});
|
||||
|
||||
ws.on("close", () => {
|
||||
// Connection closed, no action needed
|
||||
});
|
||||
});
|
||||
return;
|
||||
@@ -117,7 +140,57 @@ function init(server, prismaClient) {
|
||||
}
|
||||
});
|
||||
|
||||
ws.on("close", () => {
|
||||
ws.on("error", (err) => {
|
||||
// Handle WebSocket errors gracefully without crashing
|
||||
// Common errors: invalid close codes (1006), connection resets, etc.
|
||||
if (
|
||||
err.code === "WS_ERR_INVALID_CLOSE_CODE" ||
|
||||
err.message?.includes("invalid status code 1006") ||
|
||||
err.message?.includes("Invalid WebSocket frame")
|
||||
) {
|
||||
// 1006 is a special close code indicating abnormal closure
|
||||
// It cannot be sent in a close frame, but can occur when connection is lost
|
||||
console.log(
|
||||
`[agent-ws] connection error for ${apiId} (abnormal closure):`,
|
||||
err.message || err.code,
|
||||
);
|
||||
} else if (
|
||||
err.code === "ECONNRESET" ||
|
||||
err.code === "EPIPE" ||
|
||||
err.message?.includes("read ECONNRESET")
|
||||
) {
|
||||
// Connection reset errors are common and expected
|
||||
console.log(
|
||||
`[agent-ws] connection reset for ${apiId}`,
|
||||
);
|
||||
} else {
|
||||
// Log other errors for debugging
|
||||
console.error(
|
||||
`[agent-ws] error for ${apiId}:`,
|
||||
err.message || err.code || err,
|
||||
);
|
||||
}
|
||||
|
||||
// Clean up connection on error
|
||||
const existing = apiIdToSocket.get(apiId);
|
||||
if (existing === ws) {
|
||||
apiIdToSocket.delete(apiId);
|
||||
connectionMetadata.delete(apiId);
|
||||
// Notify subscribers of disconnection
|
||||
notifyConnectionChange(apiId, false);
|
||||
}
|
||||
|
||||
// Try to close the connection gracefully if still open
|
||||
if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
|
||||
try {
|
||||
ws.close(1000); // Normal closure
|
||||
} catch {
|
||||
// Ignore errors when closing
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ws.on("close", (code, reason) => {
|
||||
const existing = apiIdToSocket.get(apiId);
|
||||
if (existing === ws) {
|
||||
apiIdToSocket.delete(apiId);
|
||||
@@ -126,7 +199,7 @@ function init(server, prismaClient) {
|
||||
notifyConnectionChange(apiId, false);
|
||||
}
|
||||
console.log(
|
||||
`[agent-ws] disconnected api_id=${apiId} total=${apiIdToSocket.size}`,
|
||||
`[agent-ws] disconnected api_id=${apiId} code=${code} reason=${reason || "none"} total=${apiIdToSocket.size}`,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -314,7 +387,7 @@ async function handleDockerStatusEvent(apiId, message) {
|
||||
status: status,
|
||||
state: status,
|
||||
updated_at: new Date(timestamp || Date.now()),
|
||||
last_checked: new Date(),
|
||||
last_checked: get_current_time(),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -139,15 +139,13 @@ class DockerImageUpdateCheck {
|
||||
console.log("🐳 Starting Docker image update check...");
|
||||
|
||||
try {
|
||||
// Get all Docker images that have a digest and repository
|
||||
// Get all Docker images that have a digest
|
||||
// Note: repository is required (non-nullable) in schema, so we don't need to check it
|
||||
const images = await prisma.docker_images.findMany({
|
||||
where: {
|
||||
digest: {
|
||||
not: null,
|
||||
},
|
||||
repository: {
|
||||
not: null,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
docker_image_updates: true,
|
||||
|
||||
@@ -3,6 +3,7 @@ const { redis, redisConnection } = require("./shared/redis");
|
||||
const { prisma } = require("./shared/prisma");
|
||||
const agentWs = require("../agentWs");
|
||||
const { v4: uuidv4 } = require("uuid");
|
||||
const { get_current_time } = require("../../utils/timezone");
|
||||
|
||||
// Import automation classes
|
||||
const GitHubUpdateCheck = require("./githubUpdateCheck");
|
||||
@@ -216,8 +217,8 @@ class QueueManager {
|
||||
api_id: api_id,
|
||||
status: "active",
|
||||
attempt_number: job.attemptsMade + 1,
|
||||
created_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
created_at: get_current_time(),
|
||||
updated_at: get_current_time(),
|
||||
},
|
||||
});
|
||||
console.log(`📝 Logged job to job_history: ${job.id} (${type})`);
|
||||
@@ -257,8 +258,8 @@ class QueueManager {
|
||||
where: { job_id: job.id },
|
||||
data: {
|
||||
status: "completed",
|
||||
completed_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
completed_at: get_current_time(),
|
||||
updated_at: get_current_time(),
|
||||
},
|
||||
});
|
||||
console.log(`✅ Marked job as completed in job_history: ${job.id}`);
|
||||
@@ -271,8 +272,8 @@ class QueueManager {
|
||||
data: {
|
||||
status: "failed",
|
||||
error_message: error.message,
|
||||
completed_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
completed_at: get_current_time(),
|
||||
updated_at: get_current_time(),
|
||||
},
|
||||
});
|
||||
console.log(`❌ Marked job as failed in job_history: ${job.id}`);
|
||||
|
||||
Reference in New Issue
Block a user