diff --git a/backend/routes/mikrotikConfigRoutes.js b/backend/routes/mikrotikConfigRoutes.js index 6bbb5eb..0fc5964 100644 --- a/backend/routes/mikrotikConfigRoutes.js +++ b/backend/routes/mikrotikConfigRoutes.js @@ -241,6 +241,14 @@ async function applyMikrotikConfig(req, res) { const mikrotikRequests = []; const body = req.body || {}; console.log('[MikroTik apply] Request body:', { serverId: body.serverId, type: body.type, dryRun: body.dryRun }); + const sendSafe = (status, data) => { + if (res.headersSent) return; + try { + res.status(status).json(data); + } catch (e) { + console.error('[MikroTik apply] sendSafe failed:', e); + } + }; try { const { serverId, type = 'all', dryRun = true } = body; if (!serverId) { @@ -344,7 +352,7 @@ async function applyMikrotikConfig(req, res) { msg.includes('Authentication') || msg.includes('login') ? 'Неверный логин или пароль' : msg, }; if (mikrotikRequests.length > 0) errPayload.mikrotikRequests = mikrotikRequests; - return res.status(500).json(errPayload); + sendSafe(500, errPayload); } } diff --git a/backend/server.js b/backend/server.js index 06473f7..e0dca61 100644 --- a/backend/server.js +++ b/backend/server.js @@ -450,6 +450,7 @@ app.post('/api/mikrotik/generate', mikrotikConfigRoutes.generateMikrotikConfig); app.get('/api/mikrotik/generate-interfaces', mikrotikConfigRoutes.generateInterfaces); app.get('/api/mikrotik/generate-recursive-routes', mikrotikConfigRoutes.generateRecursiveRoutes); app.post('/api/mikrotik/test-connection', mikrotikConfigRoutes.testMikrotikConnection); +app.get('/api/mikrotik/ping', (req, res) => res.json({ ok: true, ts: Date.now() })); app.post('/api/mikrotik/apply', mikrotikConfigRoutes.applyMikrotikConfig); // === MIKROTIK VALIDATION === diff --git a/frontend/src/NetworkConfigManager.jsx b/frontend/src/NetworkConfigManager.jsx index ffebbce..86847c3 100644 --- a/frontend/src/NetworkConfigManager.jsx +++ b/frontend/src/NetworkConfigManager.jsx @@ -2279,11 +2279,18 @@ function NetworkConfigManager() { } }; - const openApplyModal = (serverId) => { + const openApplyModal = async (serverId) => { setApplyServerId(serverId); setApplyResult(null); setApplyDryRun(true); setApplyModalOpen(true); + try { + const r = await fetch('/api/mikrotik/ping'); + const d = await r.json().catch(() => ({})); + console.log('[MikroTik apply] Backend ping:', r.ok ? 'OK' : 'FAIL', d); + } catch (e) { + console.warn('[MikroTik apply] Backend ping failed:', e.message); + } }; // === Генерация кода MikroTik только для одного интерфейса ===