cljs-devtools icon indicating copy to clipboard operation
cljs-devtools copied to clipboard

Custom formatter for ex-info thrown by cljs.spec

Open olivergeorge opened this issue 8 years ago • 8 comments

Currently it's quite tricky to get good output from cljs.spec. Reason being that the ex-info thrown includes the full spec commentary in ex-message. This includes the serialised val which failed. In my case this can fill the console many times over.

Alex Miller recommended catching these exceptions and using the ex-data to present the spec nicely. (e.g. don't print the ex-message to the console). This would be fine except it's difficult to catch all errors due to the nature of how UI code executes (react render loop, re-frame dispatch queue, callbacks)

How about automatically detecting and pretty formatting ex-info errors thrown by cljs.spec?

olivergeorge avatar Jul 29 '16 05:07 olivergeorge

I like your idea. But how do you think cljs-devtools could implement this without this feature being framework-specific?

darwin avatar Jul 29 '16 20:07 darwin

Ok, thinking about this more. We could install window.onerror handler as we do with sanity hints[1] and do some magic there. But if "framework" catches the exceptions, we are out of luck.

[1] https://github.com/binaryage/cljs-devtools/blob/868cf1e33623781d7c0bbc11e9c2c313ab0c6dca/src/lib/devtools/sanity_hints.cljs#L123

darwin avatar Jul 29 '16 20:07 darwin

That sounds like a good approach.

I guess the other possibility is to extend IFormat for ExceptionInfo and use ex-data to enable special treatment.

olivergeorge avatar Jul 31 '16 23:07 olivergeorge

To keep the ball rolling, I have just tested ExceptionInfo behaviour[1].

Currently cljs-devtools has pretty nice behaviour, it presents the error printed with IPrintWithWriter protocol[2]. The implementation is questionable because they are re-implementing clojurescript map printer in there, but that is not essential to our issue at hand.

I think nothing is stopping you overriding IPrintWithWriter on ExceptionInfo and doing something better there (e.g. abbreviating long messages).

But I agree that we could do even better job with IFormat. We could reuse string abbreviation logic already implemented[3] in devtools and present other parts as expandable data.

[1] https://github.com/binaryage/cljs-devtools-sample/commit/6422ec1b69b7357e404bcceebed1cac4e994cf72 [2] https://github.com/clojure/clojurescript/blob/e2db5d9ff8cb6a099ebc2a8cd379385bf4649b38/src/main/cljs/cljs/core.cljs#L10283-L10286 [3] https://github.com/binaryage/cljs-devtools/blob/9c2eda4f289761d88d61d0088a167bae594b4b0c/src/lib/devtools/formatters/markup.cljs#L89

darwin avatar Aug 03 '16 18:08 darwin

btw. here is how it looks currently:

darwin avatar Aug 03 '16 18:08 darwin

Actually this ExceptionInfo is not a fully working CLJS type, so cljs-devtools do not treat it correctly under all circumstances.

I went down the rabbit hole and proposed a solution upstream: http://dev.clojure.org/jira/browse/CLJS-1722

Let's wait for its resolution before moving forward.

darwin avatar Aug 03 '16 23:08 darwin

Interesting. Thanks. (I'd love to know what Bruce is thinking about presenting spec errors. Can't help but think he'll be the trendsetter.)

olivergeorge avatar Aug 03 '16 23:08 olivergeorge

This would be a killer feature!

arichiardi avatar Jun 18 '17 21:06 arichiardi