From 0616035dfc175c390cf920cb53cb55176039ffa3 Mon Sep 17 00:00:00 2001 From: Antonin Stefanutti Date: Thu, 29 Apr 2021 10:59:41 +0200 Subject: [PATCH] Better error handling in pods table widget --- lib/ui/dashboard.js | 48 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/lib/ui/dashboard.js b/lib/ui/dashboard.js index c284100..35b26fc 100644 --- a/lib/ui/dashboard.js +++ b/lib/ui/dashboard.js @@ -58,6 +58,18 @@ class Dashboard extends EventEmitter { }, }); + let pods_table_text; + function pods_table_message(text, options = {}) { + if (pods_table_text) pods_table_text.destroy(); + pods_table_text = blessed.text(Object.assign({ + parent : pods_table, + tags : true, + top : 'center', + left : 'center', + content : text, + }, options)); + } + const resources = blessed.box({ label : 'Resources', parent : screen, @@ -461,12 +473,10 @@ class Dashboard extends EventEmitter { .catch(error => { // cancelled if (!error) return; - // let's skip expected errors if the pod is being deleted if (k8s.isPodTerminating(getPodByUid(pod.metadata.uid)) && (error.name === 'Kubebox' || error.response)) { return; } - if (error.name === 'Kubebox') { graphs.forEach(g => g.message(error.message)); } else if (error.response) { @@ -482,6 +492,7 @@ class Dashboard extends EventEmitter { } else { console.error(error.stack); } + screen.render(); }); } @@ -671,6 +682,7 @@ class Dashboard extends EventEmitter { this.reset = function (page) { // cancel current running tasks and open requests cancellations.run('dashboard'); + // reset state current_namespace = null; pod_selected = null; container_selected = null; @@ -678,6 +690,10 @@ class Dashboard extends EventEmitter { // reset dashboard widgets pods_table.setLabel('Pods'); pods_table.setData([]); + if (pods_table_text) { + pods_table_text.destroy(); + pods_table_text = null; + } // reset focus if (pods_table.detached) { page.focus = pods_table; @@ -696,39 +712,49 @@ class Dashboard extends EventEmitter { current_namespace = namespace; let listPodsError; // FIXME: should be cancellable - const promise = until(client.pods(current_namespace).get()) + const promise = until(client.pods(namespace).get()) .do(pods_table, pods_table.setLabel) - .spin(s => `${s} Pods {grey-fg}[${current_namespace}]{/grey-fg}`) - .done(_ => `Pods {grey-fg}[${current_namespace}]{/grey-fg}`) + .spin(s => `${s} Pods {grey-fg}[${namespace}]{/grey-fg}`) + .done(_ => `Pods {grey-fg}[${namespace}]{/grey-fg}`) .then(response => { pods_list = JSON.parse(response.body.toString('utf8')); pods_list.items = pods_list.items || []; updatePodsTable(); }).catch(error => { listPodsError = error; + pods_table_message(`{red-bg}Error: ${error.message}{/red-bg}`); + screen.render(); return Promise.reject(error); }); promise .then(() => { - console.debug(`Watching for pods changes in namespace ${current_namespace} ...`); + console.debug(`Watching for pods changes in namespace ${namespace} ...`); screen.render(); const id = setInterval(refreshPodAges, 1000); cancellations.add('dashboard.refreshPodAges', () => clearInterval(id)); - const { promise, cancellation } = client.pods(current_namespace) + const { promise, cancellation } = client.pods(namespace) .watch(pods_list.metadata.resourceVersion) - .get({ generator: watchPodChanges }); + .get({ + generator: function* () { + yield* watchPodChanges(namespace); + } + }); cancellations.add('dashboard', cancellation); return promise; }) .catch(error => { - if (!listPodsError) console.error(error.stack); + if (!listPodsError) { + pods_table_message(`{red-bg}Error: ${error.message}{/red-bg}`); + console.error(error.stack); + screen.render(); + } }); return promise; } - function* watchPodChanges() { + function* watchPodChanges(namespace) { const index = object => pods_list.items.findIndex(pod => pod.metadata.uid === object.metadata.uid); let change; try { @@ -785,7 +811,7 @@ class Dashboard extends EventEmitter { } // retry the pods list watch request cancellations.run('dashboard.refreshPodAges'); - dashboard.run(current_namespace).catch(error => console.error(error.stack)); + dashboard.run(namespace).catch(error => console.error(error.stack)); } function refreshPodAges() {