Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcfd9e9b65 | ||
|
|
b13a8c343f | ||
|
|
42f224ab93 | ||
|
|
0b4797f38c | ||
|
|
b710f68d21 |
No files matched your search
Generated
+1
@@ -122,6 +122,7 @@
|
|||||||
"version": "13.0.3",
|
"version": "13.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-13.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-13.0.3.tgz",
|
||||||
"integrity": "sha512-RbOBxmLBG8uvFUc15X9+9SFemKcQ0WBuISBVkpuiaUB2qblC8UWlHEjdWVoZ8AdhSwmoEgsiXKfopX0CQxaACQ==",
|
"integrity": "sha512-RbOBxmLBG8uvFUc15X9+9SFemKcQ0WBuISBVkpuiaUB2qblC8UWlHEjdWVoZ8AdhSwmoEgsiXKfopX0CQxaACQ==",
|
||||||
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-addon-api": "^8.0.0"
|
"node-addon-api": "^8.0.0"
|
||||||
|
|||||||
@@ -6,6 +6,26 @@ const http = require('http');
|
|||||||
const { randomUUID } = require('crypto');
|
const { randomUUID } = require('crypto');
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
|
||||||
|
// Prevent HTTP parser errors (e.g. "Data after Connection: close") and other
|
||||||
|
// transient async errors from crashing the process.
|
||||||
|
process.on('uncaughtException', (err) => {
|
||||||
|
if (err.code === 'HPE_INVALID_CONSTANT' || (err.message && err.message.includes('Parse Error'))) {
|
||||||
|
console.error('HTTP parse error (swallowed):', err.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.error('Uncaught exception:', err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (reason) => {
|
||||||
|
const msg = reason instanceof Error ? reason.message : String(reason);
|
||||||
|
if (msg.includes('Parse Error')) {
|
||||||
|
console.error('HTTP parse error (swallowed):', msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.error('Unhandled rejection:', reason);
|
||||||
|
});
|
||||||
|
|
||||||
const db = require('./database');
|
const db = require('./database');
|
||||||
const scheduler = require('./scheduler');
|
const scheduler = require('./scheduler');
|
||||||
const monitorService = require('./monitorService');
|
const monitorService = require('./monitorService');
|
||||||
|
|||||||
@@ -31,9 +31,14 @@ function parseHostPort(urlString, fallbackPort) {
|
|||||||
|
|
||||||
class MonitorService {
|
class MonitorService {
|
||||||
constructor() {
|
constructor() {
|
||||||
// Keep-alive agents for pooled HTTP/S connections
|
// Disable keep-alive to avoid "Parse Error: Data after Connection: close"
|
||||||
this.httpAgent = new http.Agent({ keepAlive: true, maxSockets: 50 });
|
// crashes. Keep-alive connection reuse causes the HTTP parser to throw
|
||||||
this.httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 50 });
|
// when a monitored server sends extra data after Connection: close — the
|
||||||
|
// socket-level error becomes an uncaught exception that kills the process.
|
||||||
|
// Monitoring checks are infrequent enough that connection pooling provides
|
||||||
|
// no meaningful benefit.
|
||||||
|
this.httpAgent = new http.Agent({ keepAlive: false });
|
||||||
|
this.httpsAgent = new https.Agent({ keepAlive: false });
|
||||||
|
|
||||||
// Circuit breaker for HTTP checks (5 failures before opening, 60s reset)
|
// Circuit breaker for HTTP checks (5 failures before opening, 60s reset)
|
||||||
this.httpCircuitBreaker = new CircuitBreaker(5, 60000, this.isTransientError);
|
this.httpCircuitBreaker = new CircuitBreaker(5, 60000, this.isTransientError);
|
||||||
|
|||||||
Reference in new issue
Block a user