尝试抓住忽略?

时间:2017-11-07 11:16:05

标签: jdbc clojure

以下代码在db中创建一个新表。我希望它能捕获任何sql错误,并在表已经存在的情况下继续运行。但是,当我执行代码时,如果表已经存在,我会按预期得到异常但代码在编译期间退出。 try catch被忽略了吗?

代码:

 (ns app.storage
  (:import com.mchange.v2.c3p0.ComboPooledDataSource
           (clojure.lang ExceptionInfo))
  (:require [clojure.java.jdbc :refer :all]))

(def db {
         :classname   "org.sqlite.JDBC"
         :subprotocol "sqlite"
         :subname     "src/storage/journal.db"
         })

(defn create-db []
  (try
    (db-do-commands db
                    (create-table-ddl :entry
                                      [:id :primary :key]
                                      [:account "varchar(255)"]
                                      [:timestamp "timestamp"]
                                      [:debt "double(9,2)"]
                                      [:credit "double(9,2)"]))

    (catch ExceptionInfo e
      (println e))))

(create-db)

例外:

    Exception in thread "main" java.sql.BatchUpdateException: batch entry 0: [SQLITE_ERROR] SQL error or missing database (table entry already exists), compiling:(app/storage.clj:29:21)
    at clojure.lang.Compiler.load(Compiler.java:7142)
    at clojure.lang.RT.loadResourceScript(RT.java:370)
    at clojure.lang.RT.loadResourceScript(RT.java:361)
    at clojure.lang.RT.load(RT.java:440)
    at clojure.lang.RT.load(RT.java:411)
    at clojure.core$load$fn__5066.invoke(core.clj:5641)
    at clojure.core$load.doInvoke(core.clj:5640)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5446)
    at clojure.core$load_lib$fn__5015.invoke(core.clj:5486)
    at clojure.core$load_lib.doInvoke(core.clj:5485)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$load_libs.doInvoke(core.clj:5524)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:628)
    at clojure.core$use.doInvoke(core.clj:5618)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at app.entry$eval2001$loading__4958__auto____2002.invoke(entry.clj:1)
    at app.entry$eval2001.invoke(entry.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6703)
    at clojure.lang.Compiler.eval(Compiler.java:6692)
    at clojure.lang.Compiler.load(Compiler.java:7130)
    at clojure.lang.RT.loadResourceScript(RT.java:370)
    at clojure.lang.RT.loadResourceScript(RT.java:361)
    at clojure.lang.RT.load(RT.java:440)
    at clojure.lang.RT.load(RT.java:411)
    at clojure.core$load$fn__5066.invoke(core.clj:5641)
    at clojure.core$load.doInvoke(core.clj:5640)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5446)
    at clojure.core$load_lib$fn__5015.invoke(core.clj:5486)
    at clojure.core$load_lib.doInvoke(core.clj:5485)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$load_libs.doInvoke(core.clj:5524)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:628)
    at clojure.core$use.doInvoke(core.clj:5618)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at app.handler$eval1687$loading__4958__auto____1688.invoke(handler.clj:1)
    at app.handler$eval1687.invoke(handler.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6703)
    at clojure.lang.Compiler.eval(Compiler.java:6692)
    at clojure.lang.Compiler.load(Compiler.java:7130)
    at clojure.lang.RT.loadResourceScript(RT.java:370)
    at clojure.lang.RT.loadResourceScript(RT.java:361)
    at clojure.lang.RT.load(RT.java:440)
    at clojure.lang.RT.load(RT.java:411)
    at clojure.core$load$fn__5066.invoke(core.clj:5641)
    at clojure.core$load.doInvoke(core.clj:5640)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5446)
    at clojure.core$load_lib$fn__5015.invoke(core.clj:5486)
    at clojure.core$load_lib.doInvoke(core.clj:5485)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$load_libs.doInvoke(core.clj:5524)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$require.doInvoke(core.clj:5607)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at user$eval5.invoke(form-init1139882819344867506.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6703)
    at clojure.lang.Compiler.eval(Compiler.java:6692)
    at clojure.lang.Compiler.load(Compiler.java:7130)
    at clojure.lang.Compiler.loadFile(Compiler.java:7086)
    at clojure.main$load_script.invoke(main.clj:274)
    at clojure.main$init_opt.invoke(main.clj:279)
    at clojure.main$initialize.invoke(main.clj:307)
    at clojure.main$null_opt.invoke(main.clj:342)
    at clojure.main$main.doInvoke(main.clj:420)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:383)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.Var.applyTo(Var.java:700)
    at clojure.main.main(main.java:37)
Caused by: java.sql.BatchUpdateException: batch entry 0: [SQLITE_ERROR] SQL error or missing database (table entry already exists)
    at org.sqlite.Stmt.executeBatch(Stmt.java:226)
    at clojure.java.jdbc$execute_batch.invoke(jdbc.clj:400)
    at clojure.java.jdbc$db_do_commands$fn__2331.invoke(jdbc.clj:671)
    at clojure.java.jdbc$db_transaction_STAR_.doInvoke(jdbc.clj:580)
    at clojure.lang.RestFn.invoke(RestFn.java:425)
    at clojure.java.jdbc$db_do_commands.doInvoke(jdbc.clj:670)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:628)
    at clojure.java.jdbc$db_do_commands.doInvoke(jdbc.clj:677)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:630)
    at clojure.java.jdbc$db_do_commands.doInvoke(jdbc.clj:664)
    at clojure.lang.RestFn.invoke(RestFn.java:425)
    at app.storage$create_db.invoke(storage.clj:21)
    at app.storage$eval2445.invoke(storage.clj:33)
    at clojure.lang.Compiler.eval(Compiler.java:6703)
    at clojure.lang.Compiler.load(Compiler.java:7130)
    ... 76 more
Subprocess failed

1 个答案:

答案 0 :(得分:5)

我认为问题在于catch正在尝试捕获ExceptionInfo类型的异常。尝试将其更改为ExceptionThrowable,看看它是否捕获了异常。

(catch Exception e

请注意,在堆栈跟踪中,抛出的异常类型为java.sql.BatchUpdateException,它不会从clojure.lang.ExceptionInfo继承。 通常通过调用ExceptionInfodocs here来创建ex-info个例外。您的catch只会捕获指定类型(或其子类型)的异常。