diff --git a/WDL/Error.py b/WDL/Error.py index d9b730a1..5f9e48b4 100644 --- a/WDL/Error.py +++ b/WDL/Error.py @@ -185,10 +185,12 @@ def __init__(self, node: SourceNode, message: str) -> None: class UnknownIdentifier(ValidationError): - def __init__(self, node: SourceNode) -> None: + def __init__(self, node: SourceNode, message: Optional[str] = None) -> None: # avoiding circular dep: # assert isinstance(node, WDL.Expr.Ident) - super().__init__(node, "Unknown identifier " + str(node)) + if not message: + message = "Unknown identifier " + str(node) + super().__init__(node, message) class NoSuchInput(ValidationError): diff --git a/WDL/Expr.py b/WDL/Expr.py index ff2f3784..ad4780bf 100644 --- a/WDL/Expr.py +++ b/WDL/Expr.py @@ -956,7 +956,11 @@ def _infer_type(self, type_env: Env.Bindings[Type.Base]) -> Type.Base: # attempt to resolve "expr.member" and if that works, transform # expr to Ident("expr.member") if self.expr._ident + "." + self.member not in type_env: - raise Error.UnknownIdentifier(self) from None + message = None + if type_env.has_namespace(self.expr._ident): + # specific error message when namespace exists but member doesn't + message = f"No {self.member} in namespace {self.expr._ident}" + raise Error.UnknownIdentifier(self, message=message) from None self.expr = Ident(self.pos, self._ident) self.expr.infer_type(type_env, self._stdlib, self._check_quant) self.member = None diff --git a/tests/test_1doc.py b/tests/test_1doc.py index 259bfe19..20c24ac7 100644 --- a/tests/test_1doc.py +++ b/tests/test_1doc.py @@ -811,7 +811,7 @@ def test_errors(self): } """ doc = WDL.parse_document(doc) - with self.assertRaises(WDL.Error.UnknownIdentifier): + with self.assertRaisesRegex(WDL.Error.UnknownIdentifier, " in namespace "): doc.typecheck() doc = r"""