以下代码在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
答案 0 :(得分:5)
我认为问题在于catch
正在尝试捕获ExceptionInfo
类型的异常。尝试将其更改为Exception
或Throwable
,看看它是否捕获了异常。
(catch Exception e
请注意,在堆栈跟踪中,抛出的异常类型为java.sql.BatchUpdateException
,它不会从clojure.lang.ExceptionInfo
继承。
通常通过调用ExceptionInfo
,docs here来创建ex-info
个例外。您的catch
只会捕获指定类型(或其子类型)的异常。