diff --git a/scripts/lib/control-pane/control-plane-view-ui.js b/scripts/lib/control-pane/control-plane-view-ui.js index 30ffd831b..fd30f6e1b 100644 --- a/scripts/lib/control-pane/control-plane-view-ui.js +++ b/scripts/lib/control-pane/control-plane-view-ui.js @@ -281,8 +281,23 @@ function renderControlPlaneViewHtml() { !Number.isFinite(data.thresholds.ta) || !Number.isFinite(data.thresholds.ra)) { throw new Error('Invalid control-plane view'); } + var previous = view; + var drawStarted = false; view = Object.assign({}, data); - renderEvents(); renderLanes(); draw(); + try { + renderEvents(); renderLanes(); + drawStarted = true; + draw(); + } catch (error) { + view = previous; + try { + renderEvents(); renderLanes(); + if (drawStarted) draw(); + } catch (_) { + // Keep the accepted model even if the DOM cannot be restored. + } + throw error; + } var c = view.counts || {}; var summary = (c.tasks || 0) + ' tasks in ' + (c.lanes || 0) + ' lanes, ' + (c.advisories || 0) + ' advisories, ' + (c.resolutions || 0) + ' steering. ' + diff --git a/tests/lib/control-plane-view-ui.test.js b/tests/lib/control-plane-view-ui.test.js index ef4646166..fc433a7dd 100644 --- a/tests/lib/control-plane-view-ui.test.js +++ b/tests/lib/control-plane-view-ui.test.js @@ -103,6 +103,7 @@ async function render(responses) { const timers = []; const timeouts = []; const queue = responses.slice(); + const listeners = new Map(); let jsonReads = 0; const document = { getElementById(id) { if (!elements.has(id)) elements.set(id, element(null, context)); return elements.get(id); }, @@ -115,7 +116,7 @@ async function render(responses) { const code = html.slice(start + '