Clojure

alias function gives confusing message if using unknown namespace

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: Release 1.3
  • Component/s: None
  • Labels:
    None
  • Patch:
    Code and Test
  • Approval:
    Ok

Description

This is really a request for improved error handling. If you use (alias) with a namespace that is not known it throws an NPE with imho a confusing error message.

Example:

user=> (alias 'R 'S) 
java.lang.NullPointerException: Expecting Symbol + Namespace (NO_SOURCE_FILE:0)
user=> (.printStackTrace *e)
nil
user=> java.lang.NullPointerException: Expecting Symbol + Namespace (NO_SOURCE_FILE:0)
        at clojure.lang.Compiler.eval(Compiler.java:5348)
        at clojure.lang.Compiler.eval(Compiler.java:5300)
        at clojure.core$eval__4281.invoke(core.clj:2135)
        at clojure.main$repl__6358$read_eval_print__6366.invoke(main.clj:183)
        at clojure.main$repl__6358.doInvoke(main.clj:200)
        at clojure.lang.RestFn.invoke(RestFn.java:422)
        at clojure.main$repl_opt__6392.invoke(main.clj:254)
        at clojure.main$main__6418.doInvoke(main.clj:347)
        at clojure.lang.RestFn.invoke(RestFn.java:398)
        at clojure.lang.Var.invoke(Var.java:361)
        at clojure.lang.AFn.applyToHelper(AFn.java:161)
        at clojure.lang.Var.applyTo(Var.java:482)
        at clojure.main.main(main.java:37)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at jline.ConsoleRunner.main(ConsoleRunner.java:69)
Caused by: java.lang.NullPointerException: Expecting Symbol + Namespace
        at clojure.lang.Namespace.addAlias(Namespace.java:184)
        at clojure.core$alias__4566.invoke(core.clj:2892)
        at user$eval__11.invoke(NO_SOURCE_FILE:7)
        at clojure.lang.Compiler.eval(Compiler.java:5332)
        ... 17 more
</code></pre>

And the clj:

<pre><code>(defn alias
  "Add an alias in the current namespace to another
  namespace. Arguments are two symbols: the alias to be used, and
  the symbolic name of the target namespace. Use :as in the ns macro in preference
  to calling this directly."
  [alias namespace-sym]
  (.addAlias *ns* alias (find-ns namespace-sym)))

Clearly, the clojure is doing find-ns and the namespace is not known so it passes a null down. Seems like the code in either the clj or java level could say "Hey dummy, you used an unknown namespace" instead of "Expecting Symbol + Namespace". Maybe this would be useful as an additional sentence in the alias doc string too.

Activity

Hide
Assembla Importer added a comment -
Show
Assembla Importer added a comment - Converted from http://www.assembla.com/spaces/clojure/tickets/320
Hide
Assembla Importer added a comment -

aaron said: Tried to submit a patch but keep getting 500 errors on assembla. I'll try again later, but i'll paste the patch in here so it is somewhere else.

From 32c32d65ec43598f36872a742bdebec5907d17d7 Mon Sep 17 00:00:00 2001
From: Aaron Bedra <aaron@aaronbedra.com>
Date: Tue, 26 Oct 2010 23:34:55 -0400
Subject: [PATCH] clarifying error message on alias


src/jvm/clojure/lang/Namespace.java | 9 +++++++--
1 files changed, 7 insertions, 2 deletions

diff --git a/src/jvm/clojure/lang/Namespace.java b/src/jvm/clojure/lang/Namespace.java
index 1936973..87a9082 100644
— a/src/jvm/clojure/lang/Namespace.java
+++ b/src/jvm/clojure/lang/Namespace.java
@@ -210,8 +210,13 @@ public Namespace lookupAlias(Symbol alias){
}

public void addAlias(Symbol alias, Namespace ns){

  • if (alias == null || ns == null)
  • throw new NullPointerException("Expecting Symbol + Namespace");
    + if (alias == null && ns == null)
    + throw new NullPointerException("Received unknown alias and namespace");
    + else if (ns == null)
    + throw new NullPointerException("Received unknown namespace");
    + else if (alias == null)
    + throw new NullPointerException("Received unknown alias");
    +
    IPersistentMap map = getAliases();
    while(!map.containsKey(alias))
    {

    • 1.7.3.2
Show
Assembla Importer added a comment - aaron said: Tried to submit a patch but keep getting 500 errors on assembla. I'll try again later, but i'll paste the patch in here so it is somewhere else. From 32c32d65ec43598f36872a742bdebec5907d17d7 Mon Sep 17 00:00:00 2001 From: Aaron Bedra <aaron@aaronbedra.com> Date: Tue, 26 Oct 2010 23:34:55 -0400 Subject: [PATCH] clarifying error message on alias — src/jvm/clojure/lang/Namespace.java | 9 +++++++-- 1 files changed, 7 insertions, 2 deletions diff --git a/src/jvm/clojure/lang/Namespace.java b/src/jvm/clojure/lang/Namespace.java index 1936973..87a9082 100644 — a/src/jvm/clojure/lang/Namespace.java +++ b/src/jvm/clojure/lang/Namespace.java @@ -210,8 +210,13 @@ public Namespace lookupAlias(Symbol alias){ } public void addAlias(Symbol alias, Namespace ns){
  • if (alias == null || ns == null)
  • throw new NullPointerException("Expecting Symbol + Namespace"); + if (alias == null && ns == null) + throw new NullPointerException("Received unknown alias and namespace"); + else if (ns == null) + throw new NullPointerException("Received unknown namespace"); + else if (alias == null) + throw new NullPointerException("Received unknown alias"); + IPersistentMap map = getAliases(); while(!map.containsKey(alias)) {
    • 1.7.3.2
Hide
Stuart Halloway added a comment -

If we are going to the trouble of improving the error message, then we should have the error message refer to the arg that caused the problem.

By handling the error in the internal method addAlias instead of the API fn alias, you lose the value passed in, and cannot say "You said foo, but foo isn't a namespace."

Patch that adds error handling to alias in core.clj would be welcome.

Show
Stuart Halloway added a comment - If we are going to the trouble of improving the error message, then we should have the error message refer to the arg that caused the problem. By handling the error in the internal method addAlias instead of the API fn alias, you lose the value passed in, and cannot say "You said foo, but foo isn't a namespace." Patch that adds error handling to alias in core.clj would be welcome.
Hide
David Rupp added a comment -

I had some private correspondence with Aaron about this attempt. As he rightly says, it does handle only the case where the aliased namespace is nil, not when the alias itself is nil, but I think that is by far the most likely scenario. On the plus side, it does so in core.clj using existing API. Maybe a good starting point?

Show
David Rupp added a comment - I had some private correspondence with Aaron about this attempt. As he rightly says, it does handle only the case where the aliased namespace is nil, not when the alias itself is nil, but I think that is by far the most likely scenario. On the plus side, it does so in core.clj using existing API. Maybe a good starting point?
Hide
Aaron Bedra added a comment -

After another review of David's patch I think it is the way to go here. Please use his patch.

Show
Aaron Bedra added a comment - After another review of David's patch I think it is the way to go here. Please use his patch.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: