improve unknown error parsing

This commit is contained in:
checktheroads 2020-03-23 01:10:53 -07:00
parent 6034735e23
commit 27e25e757a
2 changed files with 60 additions and 13 deletions

View file

@ -7,7 +7,6 @@ hyperglass-frr API calls, returns the output back to the front end.
"""
# Standard Library
import re
import signal
from ssl import CertificateError
@ -23,7 +22,7 @@ from netmiko import (
)
# Project
from hyperglass.util import log
from hyperglass.util import log, parse_exception
from hyperglass.encode import jwt_decode, jwt_encode
from hyperglass.constants import Supported
from hyperglass.exceptions import (
@ -317,14 +316,12 @@ class Connect:
response = "\n\n".join(responses)
log.debug(f"Output for query {self.query}:\n{response}")
except httpx.exceptions.HTTPError as rest_error:
rest_msg = " ".join(
re.findall(r"[A-Z][^A-Z]*", rest_error.__class__.__name__)
)
log.error(f"Error connecting to device {self.device.name}: {rest_msg}")
msg = parse_exception(rest_error)
log.error(f"Error connecting to device {self.device.name}: {msg}")
raise RestError(
params.messages.connection_error,
device_name=self.device.display_name,
error=rest_msg,
error=msg,
)
except OSError as ose:
log.critical(str(ose))
@ -335,13 +332,11 @@ class Connect:
)
except CertificateError as cert_error:
log.critical(str(cert_error))
msg_summary = " ".join(
re.findall(r"[A-Z][^A-Z]*", cert_error.__class__.__name__)
)
msg = parse_exception(cert_error)
raise RestError(
params.messages.connection_error,
device_name=self.device.display_name,
error=f"{msg_summary}: {cert_error}",
error=f"{msg}: {cert_error}",
)
if raw_response.status_code != 200:
@ -404,11 +399,11 @@ class Execute:
else:
output = await connect.scrape_direct()
if output == "":
if output == "" or output == "\n":
raise ResponseEmpty(
params.messages.no_output, device_name=device.display_name
)
log.debug(f"Output for query: {self.query_data}:\n{output}")
log.debug(f"Output for query: {self.query_data.json()}:\n{repr(output)}")
return output

View file

@ -616,3 +616,55 @@ def import_public_key(app_path, device_name, keystring):
raise RuntimeError("Wrote key, but written file did not match input key")
return True
def split_on_uppercase(s):
"""Split characters by uppercase letters.
From: https://stackoverflow.com/a/40382663
"""
string_length = len(s)
is_lower_around = (
lambda: s[i - 1].islower() or string_length > (i + 1) and s[i + 1].islower()
)
start = 0
parts = []
for i in range(1, string_length):
if s[i].isupper() and is_lower_around():
parts.append(s[start:i])
start = i
parts.append(s[start:])
return parts
def parse_exception(exc):
"""Parse an exception and its direct cause."""
if not isinstance(exc, BaseException):
raise TypeError(f"'{repr(exc)}' is not an exception.")
def get_exc_name(exc):
return " ".join(split_on_uppercase(exc.__class__.__name__))
def get_doc_summary(doc):
return doc.strip().split("\n")[0].strip(".")
name = get_exc_name(exc)
parsed = []
if exc.__doc__:
detail = get_doc_summary(exc.__doc__)
parsed.append(f"{name} ({detail})")
else:
parsed.append(name)
if exc.__cause__:
cause = get_exc_name(exc.__cause__)
if exc.__cause__.__doc__:
cause_detail = get_doc_summary(exc.__cause__.__doc__)
parsed.append(f"{cause} ({cause_detail})")
else:
parsed.append(cause)
return ", caused by ".join(parsed)