refactor(NetworkConfigManager, mikrotikConfigRoutes): streamline logging and error handling in MikroTik configuration application; remove redundant debug log setup
Publish Fast Tabler Docker image / build-and-push-fast (push) Failing after 2m8s

This commit is contained in:
2026-02-03 20:50:31 +07:00
parent ce107db7ea
commit 76294ab2c9
2 changed files with 25 additions and 40 deletions
-23
View File
@@ -13,9 +13,6 @@ const {
buildMikrotikConfig, buildMikrotikConfig,
} = require('../utils/mikrotikInterfaceGenerator'); } = require('../utils/mikrotikInterfaceGenerator');
const { readS3TextObject } = require('../services/s3Service'); const { readS3TextObject } = require('../services/s3Service');
if (!process.env.DEBUG?.includes('routeros-api')) {
process.env.DEBUG = (process.env.DEBUG || '') + (process.env.DEBUG ? ',' : '') + 'routeros-api:*';
}
const { RouterOSAPI } = require('node-routeros'); const { RouterOSAPI } = require('node-routeros');
const { applyBlock } = require('../services/mikrotikApplyService'); const { applyBlock } = require('../services/mikrotikApplyService');
@@ -351,24 +348,6 @@ async function applyMikrotikConfig(req, res) {
}); });
conn.on('error', (e) => log('RouterOS API error', { error: e?.message || String(e), errno: e?.errno })); conn.on('error', (e) => log('RouterOS API error', { error: e?.message || String(e), errno: e?.errno }));
conn.on('close', () => log('RouterOS API connection closed')); conn.on('close', () => log('RouterOS API connection closed'));
if (streamLogs) {
process.env.DEBUG = (process.env.DEBUG || '') + (process.env.DEBUG ? ',' : '') + 'routeros-api:*';
global.__mikrotikStreamLog = log;
const debugMod = require('debug');
const origLog = debugMod.log;
if (origLog && !debugMod._mikrotikPatched) {
debugMod._mikrotikPatched = true;
debugMod.log = function (...args) {
try {
const msg = args.map((a) => (typeof a === 'object' ? JSON.stringify(a) : String(a))).join(' ');
if (msg.includes('routeros-api') && global.__mikrotikStreamLog) {
global.__mikrotikStreamLog('node-routeros', { msg });
}
} catch (_) {}
return origLog.apply(this, args);
};
}
}
try { try {
log('Connecting to MikroTik', { host: host + ':' + port }); log('Connecting to MikroTik', { host: host + ':' + port });
await conn.connect(); await conn.connect();
@@ -408,8 +387,6 @@ async function applyMikrotikConfig(req, res) {
if (conn) try { conn.close(); } catch (_) {} if (conn) try { conn.close(); } catch (_) {}
conn = null; conn = null;
throw err; throw err;
} finally {
delete global.__mikrotikStreamLog;
} }
}; };
+25 -17
View File
@@ -2232,20 +2232,17 @@ function NetworkConfigManager() {
const requestBody = { serverId: applyServerId, type: 'all', dryRun: useDryRun }; const requestBody = { serverId: applyServerId, type: 'all', dryRun: useDryRun };
console.log('[MikroTik apply] Request:', { url: '/api/mikrotik/apply', method: 'POST', body: requestBody }); console.log('[MikroTik apply] Request:', { url: '/api/mikrotik/apply', method: 'POST', body: requestBody });
try { const doFetch = async (streamLogs) => {
const response = await fetch('/api/mikrotik/apply', { const response = await fetch('/api/mikrotik/apply', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Stream-Logs': '1', ...(streamLogs ? { 'X-Stream-Logs': '1' } : {}),
}, },
body: JSON.stringify(requestBody), body: JSON.stringify(requestBody),
}); });
console.log('[MikroTik apply] Response:', { status: response.status, ok: response.ok, url: response.url });
const contentType = response.headers.get('Content-Type') || ''; const contentType = response.headers.get('Content-Type') || '';
const isStream = contentType.includes('ndjson') || contentType.includes('x-ndjson'); const isStream = streamLogs && (contentType.includes('ndjson') || contentType.includes('x-ndjson');
let data = {}; let data = {};
if (isStream && response.body) { if (isStream && response.body) {
@@ -2263,13 +2260,9 @@ function NetworkConfigManager() {
if (!line.trim()) continue; if (!line.trim()) continue;
try { try {
const obj = JSON.parse(line); const obj = JSON.parse(line);
if (obj.t === 'log') { if (obj.t === 'log') console.log('[MikroTik apply]', obj.msg, obj);
console.log('[MikroTik apply]', obj.msg, obj); else if (obj.t === 'result') finalData = obj;
} else if (obj.t === 'result') { else if (obj.t === 'error') finalData = { ok: false, error: obj.error, mikrotikRequests: obj.mikrotikRequests };
finalData = obj;
} else if (obj.t === 'error') {
finalData = { ok: false, error: obj.error, mikrotikRequests: obj.mikrotikRequests };
}
} catch (_) {} } catch (_) {}
} }
} }
@@ -2284,6 +2277,23 @@ function NetworkConfigManager() {
} else { } else {
data = await response.json().catch(() => ({})); data = await response.json().catch(() => ({}));
} }
return { response, data };
};
try {
let response, data;
try {
const result = await doFetch(true);
response = result.response;
data = result.data;
} catch (streamErr) {
console.warn('[MikroTik apply] Stream failed, retrying without:', streamErr.message);
const result = await doFetch(false);
response = result.response;
data = result.data;
}
console.log('[MikroTik apply] Response:', { status: response.status, ok: response.ok });
if (!response.ok || data.ok === false) { if (!response.ok || data.ok === false) {
const errorMessage = data.error || data.message || `HTTP ${response.status}`; const errorMessage = data.error || data.message || `HTTP ${response.status}`;
@@ -2300,12 +2310,10 @@ function NetworkConfigManager() {
notify.success(`Применено: создано ${data.summary?.created || 0}, обновлено ${data.summary?.updated || 0}, пропущено ${data.summary?.skipped || 0}`); notify.success(`Применено: создано ${data.summary?.created || 0}, обновлено ${data.summary?.updated || 0}, пропущено ${data.summary?.skipped || 0}`);
} }
} catch (error) { } catch (error) {
const url = `${window.location.origin}/api/mikrotik/apply`; console.error('[MikroTik apply] Fetch failed:', error);
console.error('[MikroTik apply] Fetch failed:', error, '\nURL:', url);
const errMsg = error.message || 'Ошибка применения';
setApplyResult({ setApplyResult({
ok: false, ok: false,
error: errMsg + ` Сеть: ${url}`, error: (error.message || 'Ошибка применения') + ` (${window.location.origin}/api/mikrotik/apply)`,
}); });
notify.error('Не удалось применить конфигурацию по API'); notify.error('Не удалось применить конфигурацию по API');
} finally { } finally {