diff --git a/nornir_nautobot/plugins/tasks/dispatcher/default.py b/nornir_nautobot/plugins/tasks/dispatcher/default.py index 40c6255..d1cde23 100644 --- a/nornir_nautobot/plugins/tasks/dispatcher/default.py +++ b/nornir_nautobot/plugins/tasks/dispatcher/default.py @@ -24,7 +24,8 @@ from nornir_napalm.plugins.tasks import napalm_configure, napalm_get from nornir_netmiko.tasks import netmiko_send_command from nornir_nautobot.exceptions import NornirNautobotException -from nornir_nautobot.utils.helpers import make_folder, is_truthy +from nornir_nautobot.utils.helpers import make_folder, get_stack_trace, is_truthy + _logger = logging.getLogger(__name__) @@ -148,6 +149,7 @@ def generate_config( jinja_filters: Optional[dict] = None, jinja_env: Optional[jinja2.Environment] = None, ) -> Result: + # pylint: disable=too-many-locals """A small wrapper around template_file Nornir task. Args: @@ -173,29 +175,22 @@ def generate_config( jinja_env=jinja_env, )[0].result except NornirSubTaskError as exc: - if isinstance(exc.result.exception, jinja2.exceptions.UndefinedError): # pylint: disable=no-else-raise - error_msg = ( - f"`E1010:` There was a jinja2.exceptions.UndefinedError error: ``{str(exc.result.exception)}``" - ) - logger.error(error_msg, extra={"object": obj}) - raise NornirNautobotException(error_msg) - - elif isinstance(exc.result.exception, jinja2.TemplateSyntaxError): - error_msg = (f"`E1011:` There was a jinja2.TemplateSyntaxError error: ``{str(exc.result.exception)}``",) - logger.error(error_msg, extra={"object": obj}) - raise NornirNautobotException(error_msg) - - elif isinstance(exc.result.exception, jinja2.TemplateNotFound): - error_msg = f"`E1012:` There was an issue finding the template and a jinja2.TemplateNotFound error was raised: ``{str(exc.result.exception)}``" - logger.error(error_msg, extra={"object": obj}) - raise NornirNautobotException(error_msg) - - elif isinstance(exc.result.exception, jinja2.TemplateError): - error_msg = f"`E1013:` There was an issue general Jinja error: ``{str(exc.result.exception)}``" - logger.error(error_msg, extra={"object": obj}) - raise NornirNautobotException(error_msg) - - error_msg = f"`E1014:` Failed with an unknown issue. `{exc.result.exception}`" + stack_trace = get_stack_trace(exc.result.exception) + + error_mapping = { + jinja2.exceptions.UndefinedError: ("E1010", "Undefined variable in Jinja2 template"), + jinja2.TemplateSyntaxError: ("E1011", "Syntax error in Jinja2 template"), + jinja2.TemplateNotFound: ("E1012", "Jinja2 template not found"), + jinja2.TemplateError: ("E1013", "General Jinja2 template error"), + } + + for error, (code, message) in error_mapping.items(): + if isinstance(exc.result.exception, error): + error_msg = f"`{code}:` {message} - ``{str(exc.result.exception)}``\n```\n{stack_trace}\n```" + logger.error(error_msg, extra={"object": obj}) + raise NornirNautobotException(error_msg) + + error_msg = f"`E1014:` Unknown error - `{exc.result.exception}`\n```\n{stack_trace}\n```" logger.error(error_msg, extra={"object": obj}) raise NornirNautobotException(error_msg) diff --git a/nornir_nautobot/utils/helpers.py b/nornir_nautobot/utils/helpers.py index d711913..a64c86b 100644 --- a/nornir_nautobot/utils/helpers.py +++ b/nornir_nautobot/utils/helpers.py @@ -4,6 +4,7 @@ import os import logging import importlib +import traceback LOGGER = logging.getLogger(__name__) @@ -33,6 +34,12 @@ def import_string(dotted_path): return None +def get_stack_trace(exc: Exception) -> str: + """Converts the provided exception's stack trace into a string.""" + stack_trace_lines = traceback.format_exception(type(exc), exc, exc.__traceback__) + return "".join(stack_trace_lines) + + def is_truthy(arg): """Convert "truthy" strings into Booleans.