Skip to content
Permalink
Browse files

Improve dashlet error handling

Our own exceptions are displayed as before, unhandled exceptions now
result in a crash report.

Change-Id: I82dac8c6634c2db1be41101b44137868716fb867
  • Loading branch information
LarsMichelsen committed Jan 7, 2020
1 parent f46da92 commit 17fec3afadaf3487675c3c0a2339a478dd7ba1fc
Showing with 42 additions and 19 deletions.
  1. +10 −0 cmk/gui/crash_reporting.py
  2. +31 −14 cmk/gui/dashboard.py
  3. +1 −5 cmk/gui/wsgi/applications/checkmk.py
@@ -42,6 +42,7 @@
from cmk.gui.globals import html
from cmk.gui.htmllib import HTML
import cmk.gui.userdb as userdb
from cmk.gui.log import logger
from cmk.gui.plugins.views.crash_reporting import CrashReportsRowTable
from cmk.gui.exceptions import MKUserError
from cmk.gui.valuespec import (
@@ -56,6 +57,15 @@
CrashReportStore = cmk.utils.crash_reporting.CrashReportStore


def handle_exception_as_gui_crash_report(details=None, plain_error=False, fail_silently=False):
# type: (Optional[Dict], bool, bool) -> None
crash = GUICrashReport.from_exception(details=details)
CrashReportStore().save(crash)

logger.exception("Unhandled exception (Crash-ID: %s)", crash.ident_to_text())
show_crash_dump_message(crash, plain_error, fail_silently)


def show_crash_dump_message(crash, plain_text, fail_silently):
# type: (GUICrashReport, bool, bool) -> None
"""Create a crash dump from a GUI exception and display a message to the user"""
@@ -33,13 +33,15 @@
import six

from cmk.utils.type_defs import UserId # pylint: disable=unused-import
from cmk.utils.exceptions import MKException

import cmk.gui.pages
import cmk.gui.notify as notify
import cmk.gui.config as config
import cmk.gui.visuals as visuals
import cmk.gui.forms as forms
import cmk.gui.utils as utils
import cmk.gui.crash_reporting as crash_reporting
from cmk.gui.valuespec import (
Transform,
Dictionary,
@@ -537,7 +539,7 @@ def draw_dashboard(name):
mtime=board["mtime"])

except Exception as e:
dashlet_content_html = render_dashlet_exception_content(dashlet_instance, nr, e)
dashlet_content_html = render_dashlet_exception_content(dashlet_instance, e)

# Now after the dashlet content has been calculated render the whole dashlet
dashlet_container_begin(nr, dashlet)
@@ -640,20 +642,35 @@ def _update_or_show(board, dashlet_instance, is_update, mtime):
return html.drain()


def render_dashlet_exception_content(dashlet_instance, nr, e):
# type: (Dashlet, DashletId, Exception) -> Text
logger.exception("Problem while rendering dashlet %d of type %s", nr,
def render_dashlet_exception_content(dashlet_instance, e):
# type: (Dashlet, Exception) -> Text
logger.exception("Problem while rendering dashlet %d of type %s", dashlet_instance.dashlet_id,
dashlet_instance.type_name())

# Unify different string types from exception messages to a unicode string
try:
exc_txt = six.text_type(e)
except UnicodeDecodeError:
exc_txt = str(e).decode("utf-8")

return html.render_error(
_("Problem while rendering dashlet %d of type %s: %s. Have a look at <tt>var/log/web.log</tt> for "
"further information.") % (nr, dashlet_instance.type_name(), exc_txt))
with html.plugged():
if isinstance(e, MKException):
# Unify different string types from exception messages to a unicode string
try:
exc_txt = six.text_type(e)
except UnicodeDecodeError:
exc_txt = str(e).decode("utf-8")

html.header(_("Exception"), show_top_heading=False)
html.open_div(class_="dashlet", style="display:block")
html.show_error(_("Problem while rendering dashlet %d of type %s: %s. Have a look at "
"<tt>var/log/web.log</tt> for further information.") % \
(dashlet_instance.dashlet_id, dashlet_instance.type_name(), exc_txt))
html.close_div()
html.footer()
return html.drain()

crash_reporting.handle_exception_as_gui_crash_report(
details={
"dashlet_id": dashlet_instance.dashlet_id,
"dashlet_type": dashlet_instance.type_name(),
"dashlet_spec": dashlet_instance.dashlet_spec,
})
return html.drain()


def dashboard_edit_controls(name, board):
@@ -921,7 +938,7 @@ def ajax_dashlet():
is_update=True,
mtime=mtime)
except Exception as e:
dashlet_content_html = render_dashlet_exception_content(dashlet_instance, ident, e)
dashlet_content_html = render_dashlet_exception_content(dashlet_instance, e)

html.write_html(dashlet_content_html)

@@ -340,8 +340,4 @@ def _process_request(self, request, response): # pylint: disable=too-many-branc
logger.error("MKGeneralException: %s", e)

except Exception:
crash = crash_reporting.GUICrashReport.from_exception()
crash_reporting.CrashReportStore().save(crash)

logger.exception("Unhandled exception (Crash-ID: %s)", crash.ident_to_text())
crash_reporting.show_crash_dump_message(crash, _plain_error(), _fail_silently())
crash_reporting.handle_exception_as_gui_crash_report(_plain_error(), _fail_silently())

0 comments on commit 17fec3a

Please sign in to comment.
You can’t perform that action at this time.