-
Notifications
You must be signed in to change notification settings - Fork 790
Exception Handling
Exception handling is fairly similar in structure in Java and JavaScript, with one notable exception: a Java catch block matches on a type, and a JavaScript one does not. How should we resolve this in the Clojure API?
Options
- catch in ClojureScript simply has one less argument than catch in Java (catch is about platform interop, and platform interop forms can and will differ)
- catch in ClojureScript has a dummy arg that is ignored
- catch in ClojureScript tries to simulate the semantics provided in Javaland
- ClojureScript uses a different name than 'catch' so that people aren't caught off guard by the different API and semantics
I think #1 wins, and have already implemented it. Reasons:
- Platform interop will be different and look different where the semantics are different. We have already seen this with the dot (.) form.
- catch is clearly an interop form, not a manifestation of the Clojure Way to deal out-of-band with errors. The latter would be dynamic binding of a handler, which has two big advantages over exceptions: ** action at the point of failure ** composability with all our other abstractions to enable flexibility (in particular protocols and multimethods)
- If we try to fake the Java syntax or semantics, we are just encouraging people to do the wrong thing (i.e. conditionalizing error handling with types). It would suck to see people adding this to their JavaScript world because we encouraged it.
Admittedly, approach #1 will cause pain for people who are porting Clojure libs to ClojureScript. Every place that catches a Java exception will be broken, and have to be handled differently in ClojureScript. These break down into two cases:
- Places where the Java exception handling cares about the type of the exception. In this scenario you are screwed anyway, no matter what we do. The JavaScript side will already be different, and papering it over in the catch syntax won't prevent the need for separate code.
- Places where the Java exception handling does not (or should not) care about the exception type. If there are a ton of these, and people's code could be the same across Clojure and ClojureScript except for the catch block syntax, I would recommend offering a new "catchall" form. Where catch is for platform interop, catchall is the Clojure way. catchall would catch all exceptions that application code should ever catch, and would provide no way to match on type. It would map to (catch) in ClojureScript, and to (catch Exception) in Clojure.
It is worth noting that while the goog library's static typing appears to support verifying exception types at the point of a throw, but they have made no effort I can see to branch on type at the point of catch. If they don't think this is good/doable, we probably shouldn't either.
I didn't give much consideration to option 4, using a different name than "catch". The name has too much good connotation, and we have already set the pattern (with the dot operator) of using the existing names and letting them be slightly different.
- Rationale
- Quick Start
- Differences from Clojure
- [Usage of Google Closure](Google Closure)