Clojure JIRAhttp://dev.clojure.org/jira
This file is an XML representation of an issueen-us4.464925-07-2011[CLJ-1436] Deref throws an unhelpful error message when used on something not dereferencablehttp://dev.clojure.org/jira/browse/CLJ-1436
Clojure<p>Consider the following code:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(def x 1)
(def y (ref 2))
(+ @x y)</pre>
</div></div>
<p>Clojure throws a ClassCastException on cast to Future. This is a very unhelpful error message; why a Future, why not Ref, Atom etc. It would be nice if this failed more gracefully.</p>CLJ-1436Deref throws an unhelpful error message when used on something not dereferencableEnhancementMinorClosedDuplicateUnassignedPhillip LorderrormsgsnewbieTue, 3 Jun 2014 02:18:28 -0500Thu, 26 Mar 2015 10:59:57 -0500Wed, 25 Mar 2015 21:16:41 -050031<p>Attached a patch with better error messages for deref. The above example now throws:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">IllegalArgumentException class java.lang.<span class="code-object">Long</span> is not derefable clojure.core/deref (core.clj:2211)</pre>
</div></div>
<p>and e.g.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(deref (delay 1) 500 :foo)</pre>
</div></div>
<p>throws</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">IllegalArgumentException class clojure.lang.Delay is not derefable with a timeout clojure.core/deref (core.clj:2222)</pre>
</div></div><p>Patch file clj-1436-patch-2014-09-16.diff updates the deref function so that it checks whether its arg is a future before sending it to deref-future. It also updates the deref function to provide clearer error messages. If the arg is not a future, and does not implement IDeref, the patched version of deref throws an IllegalArgumentException with a message that the arg cannot be dereferenced because it is not a ref/future/etc.</p><p>Oops, I had this page open from yesterday and didn't see the patch submitted by Tobias. His has everything mine does, so I'll withdraw mine.</p><p>One suggestion: the error message might sound better as "IllegalArgumentException cannot dereference clojure.lang.Delay; not a future or reference type".</p><p>Tobias' patch does not contain the tests I had in mine, so I'm re-submitting just the tests as tests-patch.diff. If you install the tests patch without installing the deref patch, the tests will fail with the error message "Wrong exception type when passing non-IDeref/non-future to deref/@". Applying the deref patch as well will allow the tests to pass.</p><p>This patch does not seem to consider performance implications of adding this check and its impact on inlining.</p><p>Dupe of <a href="http://dev.clojure.org/jira/browse/CLJ-1162" title="Error Message when calling deref on a non-IDeref is unhelpful">CLJ-1162</a></p><p>Maybe it shouldn't be the deciding factor when selecting which duplicate ticket to close, but <a href="http://dev.clojure.org/jira/browse/CLJ-1162" title="Error Message when calling deref on a non-IDeref is unhelpful">CLJ-1162</a> has 1 vote, this one has 3. Closing this one as the duplicate is discarding those votes, unless (a) they are copied over to the older ticket, or (b) consider closing the older ticket as a duplicate of this one instead.</p><p>I pondered that myself - I usually look at votes, current status, and patch. In this case, I liked the patch on <a href="http://dev.clojure.org/jira/browse/CLJ-1162" title="Error Message when calling deref on a non-IDeref is unhelpful">CLJ-1162</a> better (although they were pretty similar). </p>Global RankPatchCode and Test