From 76294ab2c92af11fb6aacc4b1a431a890dea2732 Mon Sep 17 00:00:00 2001 From: shats Date: Tue, 3 Feb 2026 20:50:31 +0700 Subject: [PATCH] refactor(NetworkConfigManager, mikrotikConfigRoutes): streamline logging and error handling in MikroTik configuration application; remove redundant debug log setup --- backend/routes/mikrotikConfigRoutes.js | 23 -------------- frontend/src/NetworkConfigManager.jsx | 42 +++++++++++++++----------- 2 files changed, 25 insertions(+), 40 deletions(-) diff --git a/backend/routes/mikrotikConfigRoutes.js b/backend/routes/mikrotikConfigRoutes.js index 69f34f3..ba317b0 100644 --- a/backend/routes/mikrotikConfigRoutes.js +++ b/backend/routes/mikrotikConfigRoutes.js @@ -13,9 +13,6 @@ const { buildMikrotikConfig, } = require('../utils/mikrotikInterfaceGenerator'); 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 { 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('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 { log('Connecting to MikroTik', { host: host + ':' + port }); await conn.connect(); @@ -408,8 +387,6 @@ async function applyMikrotikConfig(req, res) { if (conn) try { conn.close(); } catch (_) {} conn = null; throw err; - } finally { - delete global.__mikrotikStreamLog; } }; diff --git a/frontend/src/NetworkConfigManager.jsx b/frontend/src/NetworkConfigManager.jsx index 5abcbcb..02e51a9 100644 --- a/frontend/src/NetworkConfigManager.jsx +++ b/frontend/src/NetworkConfigManager.jsx @@ -2232,20 +2232,17 @@ function NetworkConfigManager() { const requestBody = { serverId: applyServerId, type: 'all', dryRun: useDryRun }; 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', { method: 'POST', headers: { 'Content-Type': 'application/json', - 'X-Stream-Logs': '1', + ...(streamLogs ? { 'X-Stream-Logs': '1' } : {}), }, 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 isStream = contentType.includes('ndjson') || contentType.includes('x-ndjson'); + const isStream = streamLogs && (contentType.includes('ndjson') || contentType.includes('x-ndjson'); let data = {}; if (isStream && response.body) { @@ -2263,13 +2260,9 @@ function NetworkConfigManager() { if (!line.trim()) continue; try { const obj = JSON.parse(line); - if (obj.t === 'log') { - console.log('[MikroTik apply]', obj.msg, obj); - } else if (obj.t === 'result') { - finalData = obj; - } else if (obj.t === 'error') { - finalData = { ok: false, error: obj.error, mikrotikRequests: obj.mikrotikRequests }; - } + if (obj.t === 'log') console.log('[MikroTik apply]', obj.msg, obj); + else if (obj.t === 'result') finalData = obj; + else if (obj.t === 'error') finalData = { ok: false, error: obj.error, mikrotikRequests: obj.mikrotikRequests }; } catch (_) {} } } @@ -2284,6 +2277,23 @@ function NetworkConfigManager() { } else { 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) { 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}`); } } catch (error) { - const url = `${window.location.origin}/api/mikrotik/apply`; - console.error('[MikroTik apply] Fetch failed:', error, '\nURL:', url); - const errMsg = error.message || 'Ошибка применения'; + console.error('[MikroTik apply] Fetch failed:', error); setApplyResult({ ok: false, - error: errMsg + ` Сеть: ${url}`, + error: (error.message || 'Ошибка применения') + ` (${window.location.origin}/api/mikrotik/apply)`, }); notify.error('Не удалось применить конфигурацию по API'); } finally {