(instance? js/Error err) in node.js not working with core apis

559 views
Skip to first unread message

Joaquín Oltra Hernández

unread,
Feb 5, 2014, 6:42:13 AM2/5/14
to clojur...@googlegroups.com
Hi, I've got another kinky situation while trying to use some of swannodette's core.async macro/functions for dealing with async calls in node.

When dealing with
(defn error? [x]
  (instance? js/Error x))

I've noticed that this fn doesn't return true with the exceptions that the node core API returns (it works fine passing x like (Error. "")).

Here is a small example in the clojurescript node repl:
ClojureScript:cljs.user> (def fs (js/require "fs"))
#<[object Object]>
ClojureScript:cljs.user> (def e (atom nil))
#<Atom: nil>
ClojureScript:cljs.user> (.readFile fs "asdf asdf" (fn [err data]
                            (reset! e err)))
nil
ClojureScript:cljs.user> e
#<Atom: #<Error: ENOENT, open 'asdf asdf'>>
ClojureScript:cljs.user> (type @e)
#<function Error() { [native code] }>
ClojureScript:cljs.user> (isa? @e js/Error)
false
ClojureScript:cljs.user> (instance? js/Error @e)
false
ClojureScript:cljs.user> (js* "(~{} instanceof ~{})" @e js/Error)
false


And now, the same code in the node repl (which does work):
> fs = require('fs')
{ Stats: [Function],
  exists: [Function],
  [...]
> fs.readFile("asdfsadfa", function(err, data) { a = err })
undefined
> a
{ [Error: ENOENT, open 'asdfsadfa']
  errno: 34,
  code: 'ENOENT',
  path: 'asdfsadfa' }
> a instanceof Error
true


I'm super confused as by why this happens, and don't know where else to look. I've been inspecting the cljs source but it looks great and I've also tried similar code in the browser and node and it works properly:
> (try
    (.parse js/JSON "`fasd#$")
    (catch js/Error e
      (instance? js/Error e)))
true

Any idea of why this might be happening? Any pointers on what to search for? I'm I doing anything stupid?

Thanks!

ps: the <? macro and run function are supercool

David Nolen

unread,
Feb 5, 2014, 10:15:52 AM2/5/14
to clojur...@googlegroups.com
I think this is probably a cljs-noderepl issue? I believe it is run in an isolated JS context, this means you can get a instances of types from other contexts that do not correspond to the types in your own context.


It appears Error may need to be added to the contextProperties?

David


2014-02-05 Joaquín Oltra Hernández <joa...@chimeces.com>:

--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to the Google Groups "ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Joaquín Oltra

unread,
Feb 5, 2014, 11:42:31 AM2/5/14
to clojur...@googlegroups.com
It also happens in node-webkit which is where I'm developing the application. May it be because the code is comparing with the Error object from the browser and the Error comes from the node.js context?

Joaquín Oltra

unread,
Feb 5, 2014, 12:03:07 PM2/5/14
to clojur...@googlegroups.com
That is it, in node-webkit there are actually 2 js contexts, the window one and the node.js one. When getting objects from the node.js world the constructors are different by reference, since one is window.Error and the other is global.Error (each from different JS context).

Testing against the global Error obj from node returns true (as ilustrated in the attached screenshot).

I'll have a look at the noderepl to see If I can get a fix there.

I guess that for targetting node-webkit that function would end like this:

(defn error? [x]
(or (instance? js/Error x)
(instance? (.-Error js/global) x)))

Thank you very much David.

Screen Shot 2014-02-05 at 17.55.49.png
Reply all
Reply to author
Forward
0 new messages