Custom Exceptions in Clojure?

前端 未结 3 2019
醉话见心
醉话见心 2021-02-02 06:11

I\'ve been trying to create a user-defined exception in Clojure, and have been having all sorts of problems. I tried the method outlined here:

http://en.wikibooks.org/w

相关标签:
3条回答
  • 2021-02-02 06:26

    Rather than generating custom classes, there are two much simpler ways to use custom exceptions:

    1. Use slingshot - this provides custom throw+ and catch+ macros that let you throw and catch any object, as well as exceptions.

    2. In clojure 1.4 and above, you can use clojure.core/ex-info and clojure.core/ex-data to generate and catch a clojure.lang.ExceptionInfo class, which wraps a message and a map of data.

    Using this is straightforward:

    (throw (ex-info "My hovercraft is full of eels"
                    {:type :python-exception, :cause :eels}))
    
    (try (...)
      (catch clojure.lang.ExceptionInfo e
        (if (= :eels (-> e ex-data :cause))
          (println "beware the shrieking eels!")
          (println "???"))))
    

    Or in a midje test:

    (fact "should throw some eels"
        (...) 
        => (throws clojure.lang.ExceptionInfo
              #(= :eels (-> % ex-data :cause))))
    
    0 讨论(0)
  • 2021-02-02 06:29

    Make a file src/user/MyException.clj (where src is on CLASSPATH) containing:

    (ns user.MyException
      (:gen-class :extends java.lang.Exception))
    

    Check the value of *compile-path* at the REPL. Make sure this directory exists and is on CLASSPATH. Create the directory if it doesn't exist; Clojure won't do so for you.

    user> *compile-path*
    "/home/user/foo/target/classes/"
    user> (System/getProperty "java.class.path")
    ".......:/home/user/foo/target/classes/:......."
    

    Compile your class:

    user> (compile 'user.MyException)
    user.MyException
    

    If it worked, in *compile-path* you should now have files something like this:

    /home/user/foo/target/
    /home/user/foo/target/classes
    /home/user/foo/target/classes/user
    /home/user/foo/target/classes/user/MyException.class
    /home/user/foo/target/classes/user/MyException__init.class
    /home/user/foo/target/classes/user/MyException$loading__4410__auto__.class
    

    Restart your Clojure REPL / JVM to load these classes. Again, make sure these new class files are on CLASSPATH. Now you should be able to use your class:

    user> (user.MyException.)
    #<MyException user.MyException>
    
    0 讨论(0)
  • 2021-02-02 06:32

    FWIW, unless you are creating a custom exception for interop reasons you may want to consider using clojure.contrib.condition instead. It comes with a precompiled custom exception that you piggy-back custom data onto using it's API. I've been able to avoid creating many custom exceptions by using it instead. The docs are here: http://clojure.github.com/clojure-contrib/condition-api.html

    0 讨论(0)
提交回复
热议问题