Skip to content

Commit

Permalink
fix: more comprehensive error reporting for RuleExceptions (#1802)
Browse files Browse the repository at this point in the history
* fix: better error reporting for format_wildcards

* print rule name

* fix typo

* fix

* polish

* adapt to new rule error message format

* try include

* polish

* polish

* polish
  • Loading branch information
johanneskoester committed Aug 9, 2022
1 parent bc6a438 commit 1cd9512
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 13 deletions.
27 changes: 22 additions & 5 deletions snakemake/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,23 @@
from snakemake.logging import logger


def format_error(ex, lineno, linemaps=None, snakefile=None, show_traceback=False):
def format_error(
ex, lineno, linemaps=None, snakefile=None, show_traceback=False, rule=None
):
if linemaps is None:
linemaps = dict()
msg = str(ex)
if linemaps and snakefile and snakefile in linemaps:
lineno = linemaps[snakefile][lineno]
if isinstance(ex, SyntaxError):
msg = ex.msg
location = (
" in line {} of {}".format(lineno, snakefile) if lineno and snakefile else ""
)

location = ""
if lineno and snakefile:
location = f"in line {lineno} of {snakefile}"
if rule:
location = f" in rule {rule} {location}"

tb = ""
if show_traceback:
tb = "\n".join(format_traceback(cut_traceback(ex), linemaps=linemaps))
Expand Down Expand Up @@ -103,7 +109,7 @@ def print_exception(ex, linemaps):
)
)
elif isinstance(ex, RuleException):
for e in ex._include + [ex]:
for e in ex._include:
if not e.omit:
logger.error(
format_error(
Expand All @@ -114,6 +120,16 @@ def print_exception(ex, linemaps):
show_traceback=True,
)
)
logger.error(
format_error(
ex,
ex.lineno,
linemaps=linemaps,
snakefile=ex.filename,
show_traceback=True,
rule=ex.rule,
)
)
elif isinstance(ex, WorkflowError):
logger.error(
format_error(
Expand Down Expand Up @@ -204,6 +220,7 @@ def __init__(
snakefile = rule.snakefile

self._include = list(self._include)
self.rule = rule
self.lineno = lineno
self.filename = snakefile
self.omit = not message
Expand Down
10 changes: 4 additions & 6 deletions snakemake/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -938,13 +938,11 @@ def format_wildcards(self, string, **variables):
_variables.update(variables)
try:
return format(string, **_variables)
except NameError as ex:
raise RuleException("NameError: " + str(ex), rule=self.rule)
except IndexError as ex:
raise RuleException("IndexError: " + str(ex), rule=self.rule)
except Exception as ex:
raise WorkflowError(
f"Error when formatting '{string}' for rule {self.rule.name}. {ex}"
raise RuleException(
f"{ex.__class__.__name__}: {ex}, when formatting the following:\n"
+ string,
rule=self.rule,
)

def properties(self, omit_resources=["_cores", "_nodes"], **aux_properties):
Expand Down
4 changes: 2 additions & 2 deletions snakemake/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,8 +711,8 @@ def check_wildcards(self, wildcards):

if missing_wildcards:
raise RuleException(
"Could not resolve wildcards in rule {}:\n{}".format(
self.name, "\n".join(self.wildcard_names)
"Could not resolve wildcards:\n{}".format(
"\n".join(self.wildcard_names)
),
lineno=self.lineno,
snakefile=self.snakefile,
Expand Down

0 comments on commit 1cd9512

Please sign in to comment.