feat(MikrotikConfig): enhance applyMikrotikConfig and NetworkConfigManager with detailed request logging and error handling improvements
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m57s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m57s
This commit is contained in:
@@ -2229,37 +2229,49 @@ function NetworkConfigManager() {
|
||||
setApplyLoading(true);
|
||||
if (dryRunOverride !== null) setApplyResult(null);
|
||||
|
||||
const requestBody = { serverId: applyServerId, type: 'all', dryRun: useDryRun };
|
||||
console.log('[MikroTik apply] Request:', { url: '/api/mikrotik/apply', method: 'POST', body: requestBody });
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/mikrotik/apply', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
serverId: applyServerId,
|
||||
type: 'all',
|
||||
dryRun: useDryRun,
|
||||
}),
|
||||
body: JSON.stringify(requestBody),
|
||||
});
|
||||
|
||||
const data = await response.json().catch(() => ({}));
|
||||
console.log('[MikroTik apply] Response:', { status: response.status, ok: response.ok, url: response.url });
|
||||
|
||||
const data = await response.json().catch((parseErr) => {
|
||||
console.warn('[MikroTik apply] JSON parse error:', parseErr);
|
||||
return {};
|
||||
});
|
||||
|
||||
if (!response.ok || data.ok === false) {
|
||||
const errorMessage = data.error || data.message || `HTTP ${response.status}`;
|
||||
setApplyResult({ ok: false, error: errorMessage });
|
||||
console.error('[MikroTik apply] Error:', { status: response.status, error: errorMessage, data });
|
||||
setApplyResult({ ok: false, error: errorMessage, mikrotikRequests: data.mikrotikRequests });
|
||||
notify.error('Не удалось применить конфигурацию по API');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[MikroTik apply] Success:', data);
|
||||
if (data.mikrotikRequests?.length) {
|
||||
console.log('[MikroTik apply] Запросы к MikroTik:', data.mikrotikRequests);
|
||||
}
|
||||
setApplyResult(data);
|
||||
|
||||
if (data.ok && !useDryRun) {
|
||||
notify.success(`Применено: создано ${data.summary?.created || 0}, обновлено ${data.summary?.updated || 0}, пропущено ${data.summary?.skipped || 0}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[MikroTik apply] Fetch failed:', error);
|
||||
const errMsg = error.message || 'Ошибка применения';
|
||||
const hint = errMsg.includes('fetch') || errMsg.includes('Failed') ? ' Проверьте логи backend — при ERR_EMPTY_RESPONSE сервер мог не ответить.' : '';
|
||||
setApplyResult({
|
||||
ok: false,
|
||||
error: error.message || 'Ошибка применения',
|
||||
error: errMsg + hint,
|
||||
});
|
||||
notify.error('Не удалось применить конфигурацию по API');
|
||||
} finally {
|
||||
@@ -5373,9 +5385,31 @@ function NetworkConfigManager() {
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
{applyResult.mikrotikRequests?.length > 0 && (
|
||||
<details className="mt-3">
|
||||
<summary className="text-muted small cursor-pointer">Запросы к MikroTik API ({applyResult.mikrotikRequests.length})</summary>
|
||||
<pre className="bg-dark text-light p-2 rounded small mt-2 mb-0" style={{ maxHeight: '200px', overflow: 'auto', fontSize: '0.75rem' }}>
|
||||
{applyResult.mikrotikRequests.map((req, i) => (
|
||||
<div key={i}>{req.path} {Array.isArray(req.args) ? req.args.join(' ') : ''}</div>
|
||||
))}
|
||||
</pre>
|
||||
</details>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="alert alert-danger mb-0">{applyResult.error}</div>
|
||||
<>
|
||||
<div className="alert alert-danger mb-2">{applyResult.error}</div>
|
||||
{applyResult.mikrotikRequests?.length > 0 && (
|
||||
<details className="mt-2">
|
||||
<summary className="text-muted small cursor-pointer">Запросы к MikroTik API до ошибки ({applyResult.mikrotikRequests.length})</summary>
|
||||
<pre className="bg-dark text-light p-2 rounded small mt-2 mb-0" style={{ maxHeight: '200px', overflow: 'auto', fontSize: '0.75rem' }}>
|
||||
{applyResult.mikrotikRequests.map((req, i) => (
|
||||
<div key={i}>{req.path} {Array.isArray(req.args) ? req.args.join(' ') : ''}</div>
|
||||
))}
|
||||
</pre>
|
||||
</details>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user