metheus-governance-mcp-cli 0.2.229 → 0.2.230
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/gateway-transport.mjs +46 -4
- package/package.json +1 -1
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
import http from "node:http";
|
|
2
2
|
import https from "node:https";
|
|
3
3
|
|
|
4
|
+
function sleep(ms) {
|
|
5
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function isTransientGatewayTransportError(err) {
|
|
9
|
+
const code = String(err?.code || "").trim().toUpperCase();
|
|
10
|
+
const text = String(err?.message || err || "").toLowerCase();
|
|
11
|
+
if ([
|
|
12
|
+
"ECONNRESET",
|
|
13
|
+
"EPIPE",
|
|
14
|
+
"ETIMEDOUT",
|
|
15
|
+
"ECONNABORTED",
|
|
16
|
+
"EAI_AGAIN",
|
|
17
|
+
].includes(code)) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return [
|
|
21
|
+
"timeout",
|
|
22
|
+
"socket hang up",
|
|
23
|
+
"bad record mac",
|
|
24
|
+
"decryption failed",
|
|
25
|
+
"tls_get_more_records",
|
|
26
|
+
].some((item) => text.includes(item));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function withTransientGatewayRetry(operation) {
|
|
30
|
+
const maxAttempts = 3;
|
|
31
|
+
let lastError = null;
|
|
32
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
33
|
+
try {
|
|
34
|
+
return await Promise.resolve(operation(attempt));
|
|
35
|
+
} catch (err) {
|
|
36
|
+
lastError = err;
|
|
37
|
+
if (attempt >= maxAttempts || !isTransientGatewayTransportError(err)) {
|
|
38
|
+
throw err;
|
|
39
|
+
}
|
|
40
|
+
await sleep(250 * attempt);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
throw lastError || new Error("gateway transport failed");
|
|
44
|
+
}
|
|
45
|
+
|
|
4
46
|
function safeObject(value) {
|
|
5
47
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
6
48
|
return value;
|
|
@@ -32,7 +74,7 @@ export function parseToolEnvelopeFromRPCResult(resultObj, deps) {
|
|
|
32
74
|
}
|
|
33
75
|
|
|
34
76
|
export async function postJSON(urlText, timeoutSeconds, token, payload) {
|
|
35
|
-
return new Promise((resolve, reject) => {
|
|
77
|
+
return withTransientGatewayRetry(() => new Promise((resolve, reject) => {
|
|
36
78
|
const url = new URL(urlText);
|
|
37
79
|
const body = Buffer.from(JSON.stringify(payload));
|
|
38
80
|
const transport = url.protocol === "http:" ? http : https;
|
|
@@ -74,11 +116,11 @@ export async function postJSON(urlText, timeoutSeconds, token, payload) {
|
|
|
74
116
|
req.on("error", reject);
|
|
75
117
|
req.write(body);
|
|
76
118
|
req.end();
|
|
77
|
-
});
|
|
119
|
+
}));
|
|
78
120
|
}
|
|
79
121
|
|
|
80
122
|
export function getJSONWithAuthHeaders(urlText, timeoutSeconds, token, extraHeaders = {}) {
|
|
81
|
-
return new Promise((resolve, reject) => {
|
|
123
|
+
return withTransientGatewayRetry(() => new Promise((resolve, reject) => {
|
|
82
124
|
const url = new URL(urlText);
|
|
83
125
|
const transport = url.protocol === "http:" ? http : https;
|
|
84
126
|
const req = transport.request(
|
|
@@ -121,7 +163,7 @@ export function getJSONWithAuthHeaders(urlText, timeoutSeconds, token, extraHead
|
|
|
121
163
|
});
|
|
122
164
|
req.on("error", reject);
|
|
123
165
|
req.end();
|
|
124
|
-
});
|
|
166
|
+
}));
|
|
125
167
|
}
|
|
126
168
|
|
|
127
169
|
export function getJSONWithAuth(urlText, timeoutSeconds, token) {
|