nav icon indicating copy to clipboard operation
nav copied to clipboard

[BUG] Ranked statistics does not handle Graphite response errors gracefully

Open lunkwill42 opened this issue 2 years ago • 0 comments

Describe the bug

If the graphite-web API is unreachable from NAV's web process, the Ranked Statistics tool hard-crashes with a 500 error when generating a report, which in turn causes NAV's standard 500 handler to kick in. This isn't very informative to the end user (unless they know how to read the expandable traceback that is offered for potential bug reporters).

To Reproduce

Steps to reproduce the behavior in a dev environment:

  1. Shut down the graphite container
  2. Browse Ranked Statistics from the NAV toolbox
  3. Select any report and click on the Show statistics button
  4. See error

Expected behavior

The Ranked Statics view should handle the GraphiteUnreachableError and display a more friendly error message to the end user, explaining that the statistics report could not be fetched because of a problem with reaching the Graphite server. The user can be prompted to try again, or to contact their NAV admin to resolve the issue.

Screenshots

If applicable, add screenshots to help explain your problem.

Tracebacks

Environment:


Request Method: GET
Request URL: http://localhost/stats/?view=cpu_routers_highestmax&timeframe=day&rows=5&submit=Show+statistics&use_cache=on

Django Version: 3.2.13
Python Version: 3.9.2
Installed Applications:
('nav.models',
 'nav.web',
 'nav.django',
 'django.contrib.staticfiles',
 'django.contrib.sessions',
 'django.contrib.humanize',
 'django_filters',
 'crispy_forms',
 'crispy_forms_foundation',
 'rest_framework',
 'nav.auditlog',
 'nav.web.macwatch',
 'nav.web.geomap',
 'nav.portadmin.napalm',
 'nav.web.portadmin',
 'django.contrib.postgres')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'nav.web.auth.AuthenticationMiddleware',
 'nav.web.auth.AuthorizationMiddleware',
 'nav.django.legacy.LegacyCleanupMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')



Traceback (most recent call last):
  File "/usr/lib/python3.9/urllib/request.py", line 1346, in do_open
    h.request(req.get_method(), req.selector, req.data, headers,
  File "/usr/lib/python3.9/http/client.py", line 1255, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/lib/python3.9/http/client.py", line 1301, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.9/http/client.py", line 1250, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.9/http/client.py", line 1010, in _send_output
    self.send(msg)
  File "/usr/lib/python3.9/http/client.py", line 950, in send
    self.connect()
  File "/usr/lib/python3.9/http/client.py", line 921, in connect
    self.sock = self._create_connection(
  File "/usr/lib/python3.9/socket.py", line 843, in create_connection
    raise err
  File "/usr/lib/python3.9/socket.py", line 831, in create_connection
    sock.connect(sa)

During handling of the above exception ([Errno 99] Cannot assign requested address), another exception occurred:
  File "/source/python/nav/metrics/data.py", line 124, in get_metric_data
    response = urlopen(req)
  File "/usr/lib/python3.9/urllib/request.py", line 214, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.9/urllib/request.py", line 517, in open
    response = self._open(req, data)
  File "/usr/lib/python3.9/urllib/request.py", line 534, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "/usr/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.9/urllib/request.py", line 1375, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "/usr/lib/python3.9/urllib/request.py", line 1349, in do_open
    raise URLError(err)

During handling of the above exception (<urlopen error [Errno 99] Cannot assign requested address>), another exception occurred:
  File "/usr/local/lib/python3.9/dist-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.9/dist-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/source/python/nav/web/sortedstats/views.py", line 44, in index
    result = process_form(form)
  File "/source/python/nav/web/sortedstats/views.py", line 70, in process_form
    result = collect_result(view, timeframe, rows)
  File "/source/python/nav/web/sortedstats/views.py", line 92, in collect_result
    result.collect()
  File "/source/python/nav/web/sortedstats/statmodules.py", line 55, in collect
    self.data = self.get_sorted_data()
  File "/source/python/nav/web/sortedstats/statmodules.py", line 63, in get_sorted_data
    data = self.get_data()
  File "/source/python/nav/web/sortedstats/statmodules.py", line 69, in get_data
    data = get_metric_average(target, start=self.start, end=self.end)
  File "/source/python/nav/metrics/data.py", line 50, in get_metric_average
    data = get_metric_data(target, start, end)
  File "/source/python/nav/metrics/data.py", line 137, in get_metric_data
    raise errors.GraphiteUnreachableError("{0} is unreachable".format(base), err)

Exception Type: GraphiteUnreachableError at /stats/
Exception Value: http://localhost:9000/ is unreachable (<urlopen error [Errno 99] Cannot assign requested address>)

Environment (please complete the following information):

  • NAV version installed: 5.4.0 and master

lunkwill42 avatar Jul 01 '22 07:07 lunkwill42