Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Enhanced try and throw for Clojure leveraging Clojure's capabilities

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 java
Octocat-spinner-32 src
Octocat-spinner-32 test
Octocat-spinner-32 .gitignore
Octocat-spinner-32 README.org
Octocat-spinner-32 project.clj
README.org

slingshot

Enhanced throw and catch for Clojure

Provides try+ and throw+. Each is 100% compatible with Clojure and Java’s native try and throw both in source code and at runtime. Each also provides new capabilities intended to improve ease of use by leveraging Clojure’s capabilities like records and destructuring.

Clojure’s native try and throw behave much like those of Java: throw can accept objects derived from java.lang.Throwable and try selects from among catch clauses based on the class of the thrown object.

In addition to fully supporting those uses (whether they originate from Clojure code or from Java code via interop), try+ and throw+ provide these enhanced capabilities:

  • throw+ can throw any Java object, not just those whose class is derived from java.lang.Throwable.

    Clojure maps or records become an easy way to represent custom exceptions without requiring gen-class.

  • catch clauses within try+ can catch any Java object thrown by throw+, Clojure’s throw, or Java’s throw. The first catch clause whose selector matches the thrown object will execute.

    a selector can be:

    • a class name (e.g., Integer, my.clojure.record, RuntimeException), matches any instance of that class, or
    • a predicate (function of one argument like map?, a keyword, a symbol), matches any Object for which the predicate returns a truthy value, or
    • a type specifier representing a Clojure type in a hierarchy (cf., clojure.core’s type, derive, make-hierarchy, isa?). The specifier is a map with one entry where the key is a Clojure type hierarchy (or nil for the global hierarchy) and the value is a type tag: a keyword or symbol.
  • the binding to the caught exception in a catch clause is not required to be a simple symbol. It is subject to destructuring so the body of the catch clause can use the contents of a thrown collection easily.
  • in a catch clause, the context at the throw site is accessible via the hidden argument &throw-context. The context includes the thrown object, the stack trace, the environment (bound locals and their values), and a reference the context of the exception that caused the current throw. (similar to Exception’s .getCause chain)

Usage

See the tests for examples

Credits

Based on clojure.contrib.condition, data-conveying-exception, discussions on the clojure mailing list and wiki and discussions and implementations by Steve Gilardi, Phil Hagelberg, and Kevin Downey.

License

Copyright (C) 2011 Stephen C. Gilardi, Kevin Downey, and Phil Hagelberg

Distributed under the Eclipse Public License, the same as Clojure.

Something went wrong with that request. Please try again.