lambdaisland / kaocha-cljs

ClojureScript support for Kaocha
Eclipse Public License 1.0
40 stars 10 forks source link

Cryptic error if isomorphic-ws is not installed #20

Closed miikka closed 4 years ago

miikka commented 4 years ago

I tried to run kaocha-cljs without installing isomorphic-ws and ws first (see https://github.com/metosin/sieppari/pull/22) and I got this stacktrace about java.net.SocketException: Socket closed:

Stacktrace ``` % lein kaocha-cljs unit-cljs [E]Exception in thread "main" Syntax error compiling at (/private/var/folders/8s/w7wls65s2vvdml8ztk54jfch0000gn/T/form-init2260913547816842698.clj:1:125). at clojure.lang.Compiler.load(Compiler.java:7647) at clojure.lang.Compiler.loadFile(Compiler.java:7573) at clojure.main$load_script.invokeStatic(main.clj:452) at clojure.main$init_opt.invokeStatic(main.clj:454) at clojure.main$init_opt.invoke(main.clj:454) at clojure.main$initialize.invokeStatic(main.clj:485) at clojure.main$null_opt.invokeStatic(main.clj:519) at clojure.main$null_opt.invoke(main.clj:516) at clojure.main$main.invokeStatic(main.clj:598) at clojure.main$main.doInvoke(main.clj:561) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.lang.Var.applyTo(Var.java:705) at clojure.main.main(main.java:37) Caused by: java.net.SocketException: Socket closed at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118) at java.net.SocketOutputStream.write(SocketOutputStream.java:155) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) at java.io.FilterOutputStream.close(FilterOutputStream.java:158) at sun.nio.cs.StreamEncoder.implClose(StreamEncoder.java:320) at sun.nio.cs.StreamEncoder.close(StreamEncoder.java:149) at java.io.OutputStreamWriter.close(OutputStreamWriter.java:233) at java.io.BufferedWriter.close(BufferedWriter.java:266) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:167) at clojure.lang.Reflector.invokeNoArgInstanceMember(Reflector.java:438) at cljs.repl.node$close_socket.invokeStatic(node.clj:42) at cljs.repl.node$close_socket.invoke(node.clj:40) at cljs.repl.node.NodeEnv$fn__7580.invoke(node.clj:249) at cljs.repl.node.NodeEnv._tear_down(node.clj:243) at cljs.repl$tear_down.invokeStatic(repl.cljc:138) at cljs.repl$tear_down.invoke(repl.cljc:137) at kaocha.type.cljs$eval19930$fn__19932$fn__19957$fn__19964.invoke(cljs.clj:291) at kaocha.type.cljs$eval19930$fn__19932$fn__19957.invoke(cljs.clj:289) at kaocha.type.cljs$eval19930$fn__19932.invoke(cljs.clj:289) at clojure.lang.MultiFn.invoke(MultiFn.java:234) at clojure.lang.AFn.applyToHelper(AFn.java:156) at clojure.lang.AFn.applyTo(AFn.java:144) at clojure.core$apply.invokeStatic(core.clj:665) at clojure.core$apply.invoke(core.clj:660) at kaocha.plugin.capture_output$capture_output_wrap_run_hook$fn__2653$fn__2654.invoke(capture_output.clj:83) at clojure.core$with_redefs_fn.invokeStatic(core.clj:7514) at clojure.core$with_redefs_fn.invoke(core.clj:7498) at kaocha.plugin.capture_output$capture_output_wrap_run_hook$fn__2653.doInvoke(capture_output.clj:83) at clojure.lang.RestFn.invoke(RestFn.java:421) at kaocha.testable$run.invokeStatic(testable.clj:119) at kaocha.testable$run.invoke(testable.clj:110) at clojure.lang.AFn.applyToHelper(AFn.java:156) at clojure.lang.AFn.applyTo(AFn.java:144) at orchestra.spec.test$spec_checking_fn$fn__3762.doInvoke(test.cljc:127) at clojure.lang.RestFn.invoke(RestFn.java:421) at kaocha.testable$run_testable.invokeStatic(testable.clj:189) at kaocha.testable$run_testable.invoke(testable.clj:148) at kaocha.testable$run_testables.invokeStatic(testable.clj:202) at kaocha.testable$run_testables.invoke(testable.clj:192) at kaocha.api$run$fn__3150$fn__3151$fn__3152.invoke(api.clj:106) at clojure.core$with_redefs_fn.invokeStatic(core.clj:7514) at clojure.core$with_redefs_fn.invoke(core.clj:7498) at kaocha.api$run$fn__3150$fn__3151.invoke(api.clj:98) at clojure.lang.AFn.applyToHelper(AFn.java:152) at clojure.lang.AFn.applyTo(AFn.java:144) at clojure.core$apply.invokeStatic(core.clj:665) at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1973) at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1973) at clojure.lang.RestFn.invoke(RestFn.java:425) at kaocha.api$run$fn__3150.invoke(api.clj:97) at clojure.lang.AFn.applyToHelper(AFn.java:152) at clojure.lang.AFn.applyTo(AFn.java:144) at clojure.core$apply.invokeStatic(core.clj:665) at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1973) at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1973) at clojure.lang.RestFn.invoke(RestFn.java:425) at kaocha.api$run.invokeStatic(api.clj:83) at kaocha.api$run.invoke(api.clj:71) at kaocha.runner$run.invokeStatic(runner.clj:126) at kaocha.runner$run.invoke(runner.clj:68) at kaocha.runner$_main_STAR_.invokeStatic(runner.clj:156) at kaocha.runner$_main_STAR_.doInvoke(runner.clj:138) at clojure.lang.RestFn.invoke(RestFn.java:397) at clojure.lang.AFn.applyToHelper(AFn.java:152) at clojure.lang.RestFn.applyTo(RestFn.java:132) at clojure.core$apply.invokeStatic(core.clj:665) at clojure.core$apply.invoke(core.clj:660) at kaocha.runner$_main.invokeStatic(runner.clj:167) at kaocha.runner$_main.doInvoke(runner.clj:165) at clojure.lang.RestFn.invoke(RestFn.java:397) at clojure.lang.Var.invoke(Var.java:380) at user$eval3363.invokeStatic(form-init2260913547816842698.clj:1) at user$eval3363.invoke(form-init2260913547816842698.clj:1) at clojure.lang.Compiler.eval(Compiler.java:7176) at clojure.lang.Compiler.eval(Compiler.java:7166) at clojure.lang.Compiler.load(Compiler.java:7635) ... 12 more ```

The solution was to run npm i isomorphic-ws ws. The error message does not indicate what is going on. I see that there's code in kaocha.cljs.websocket-client with a more helpful message, but maybe it's not working because I did not get it?

https://github.com/lambdaisland/kaocha-cljs/blob/898048cca52a3f037ab5302e86774fa11ff26131/src/kaocha/cljs/websocket_client.cljs#L15-L24

plexus commented 4 years ago

Hi @miikka , could you try running latest master? it is now no longer to install isomorphic-ws, just installing ws is enough, and you should see a better error now.

The problem you are seeing is because calling tear-down on the node repl env can itself throw an exception, which then hides the earlier exception. I'm now swallowing any exceptions that happen in tear-down.

master contains a few other improvements as well, so it would be great if you could try it out for regressions, before I push out a new version. Thanks!

miikka commented 4 years ago

Hi! I tried master and now the error message is very helpful. That's great and this issue can be closed.

I don't have any big projects using kaocha-cljs (yet), but I played around with it a bit with Sieppari. One new, likely unintentional behavior (with version b5afd11f80b71ac95cdd8e4806fe2f0b807f16d2) that I noticed is that when a test assertion fails, the test output seems to include Kaocha debug logs:

FAIL in cljs:sieppari.context-test/terminate-test (cljs/test.js:433)
Expected:
  (not= {:queue sq/empty-queue} (sc/terminate {:queue queue}))
Actual:
  (not (not= {:queue #queue []} {:queue #queue []}))
╭───── Test output ───────────────────────────────────────────────────────
│ [kaocha.cljs.websocket-client] {:websocket/send {:type :cljs.test/message, :cljs.test/message {:type :begin-test-var, :var #'sieppari.context-test/terminate-test}, :cljs.test/testing-contexts ()}, :line 44}
│ 
│ [kaocha.cljs.websocket-client] {:websocket/send {:type :cljs.test/message, :cljs.test/message {:file "cljs/test.js", :line 433, :column 14, :type :fail, :expected (not= {:queue sq/empty-queue} (sc/terminate {:queue queue})), :actual (not (not= {:queue #queue []} {:queue #queue []})), :message nil, :kaocha.report/printed-expression "Expected:\n  (not= {:queue sq/empty-queue} (sc/terminate {:queue queue}))\nActual:\n  (not (not= {:queue #queue []} {:queue #queue []}))\n"}, :cljs.test/testing-contexts ()}, :line 44}
│ 
│ [kaocha.cljs.websocket-client] {:websocket/send {:type :cljs.test/message, :cljs.test/message {:type :pass, :expected (= (sc/terminate {:queue queue} :the-response) {:queue sq/empty-queue, :response :the-response}), :actual (#object[cljs$core$_EQ_] {:queue #queue [], :response :the-response} {:queue #queue [], :response :the-response}), :message nil}, :cljs.test/testing-contexts ()}, :line 44}
│ 
│ [kaocha.cljs.websocket-client] {:websocket/send {:type :cljs.test/message, :cljs.test/message {:type :end-test-var, :var #'sieppari.context-test/terminate-test}, :cljs.test/testing-contexts ()}, :line 44}
│ 
│ [kaocha.cljs.websocket-client] {:websocket/send {:type :kaocha.cljs.run/test-finished, :test sieppari.context-test/terminate-test}, :line 44}
╰─────────────────────────────────────────────────────────────────────────

With version 0.0-40, the report for the same test failure would not include test output at all.

plexus commented 4 years ago

Thanks for reporting this @miikka, I've addressed this in #22, and added some ways to configure the logging.