2012-04-25 71 views
1

我这个宏搭上特别烦VMware的错误(它消失,如果你重新连接)为什么这个try-catch包装宏无法捕获异常?

(defmacro with-mib-workaround 
    "this macro exists because vCenter sometimes fails to get the 
managed object reference for objects that actually do exist. Wrap 
any call to vi java in this to have it retry with an incramental delay" 
    [& body] 
    `((fn mib-workaround# [attempt# timeout#] 
     (if (> attempt# 10) 
     (do (println "giving up after too many mib-not-found failures") 
      (println "please complain to VMware about this bug...") 
      (throw (Exception. "MIB not found for existing object"))) 
     (try 
      [email protected] 
      (catch com.vmware.vim25.ManagedObjectNotFound e# 
      (println "Caught VMware ManagedObjectNotFound bug ") 
      (sleep timeout#) 
      (mib-workaround# (inc attempt#) (+ 5 timeout#)))))) 
    0 5)) 

在它的工作原理REPL测试时:

(with-mib-workaround (throw (com.vmware.vim25.ManagedObjectNotFound.))) 
Caught VMware ManagedObjectNotFound bug 
Caught VMware ManagedObjectNotFound bug 
Caught VMware ManagedObjectNotFound bug 
Caught VMware ManagedObjectNotFound bug 
Caught VMware ManagedObjectNotFound bug 
Caught VMware ManagedObjectNotFound bug 
Caught VMware ManagedObjectNotFound bug 
Caught VMware ManagedObjectNotFound bug 
Caught VMware ManagedObjectNotFound bug 
Caught VMware ManagedObjectNotFound bug 
Caught VMware ManagedObjectNotFound bug 
giving up after too many mib-not-found failures 
please complain to VMware about this bug... 
nil 

时的bug在弹出实际运行这段代码:

(with-mib-workaround 
     (relogin vm) 
     (destroy vm) 
     (clone vm) 
     (start-vm vm) 
     (sleep (* 4 60)))) 

通过捕捉落在权利

Caused by: java.lang.RuntimeException: com.vmware.vim25.ManagedObjectNotFound 
18:15:02 at com.vmware.vim25.mo.ManagedObject.retrieveObjectProperties(ManagedObject.java:158) <---- CAUSED HERE 
18:15:02 at com.vmware.vim25.mo.ManagedObject.getCurrentProperty(ManagedObject.java:179) 
18:15:02 at com.vmware.vim25.mo.ManagedEntity.getName(ManagedEntity.java:99) 
18:15:02 at sun.reflect.GeneratedMethodAccessor17.invoke(Unknown Source) 
18:15:02 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
18:15:02 at java.lang.reflect.Method.invoke(Method.java:597) 
18:15:02 at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:92) 
18:15:02 at clojure.lang.Reflector.invokeNoArgInstanceMember(Reflector.java:316) 
18:15:02 at hello_pallet.vi$get_vm_by_name$fn__4253.invoke(vi.clj:51) 
18:15:02 at clojure.core$filter$fn__3830.invoke(core.clj:2478) 
18:15:02 at clojure.lang.LazySeq.sval(LazySeq.java:42) 
18:15:02 at clojure.lang.LazySeq.seq(LazySeq.java:67) 
18:15:02 at clojure.lang.LazySeq.first(LazySeq.java:82) 
18:15:02 at clojure.lang.RT.first(RT.java:559) 
18:15:02 at clojure.core$first.invoke(core.clj:55) 
18:15:02 at hello_pallet.vi$get_vm_by_name.invoke(vi.clj:51) 
18:15:02 at hello_pallet.vi$clone_vm.invoke(vi.clj:154) 
18:15:02 at hello_pallet.core$clone.invoke(core.clj:136) 
18:15:02 at hello_pallet.core$fn__112$fn__113$mib_workaround__52__auto____114.invoke(core.clj:188) <--- FALLS PAST HERE 
18:15:02 at hello_pallet.core$fn__112$fn__113.invoke(core.clj:185) 
18:15:02 at clojure.lang.AFn.applyToHelper(AFn.java:163) 
18:15:02 at clojure.lang.AFn.applyTo(AFn.java:151) 
18:15:02 at clojure.lang.AFunction$1.doInvoke(AFunction.java:29) 
18:15:02 at clojure.lang.RestFn.applyTo(RestFn.java:137) 
18:15:02 at clojure.core$apply.invoke(core.clj:602) 
18:15:02 at pallet.action_plan$apply_action$fn__657.invoke(action_plan.clj:366) 

回答

5

看来你的例外被包裹在RuntimeException; Clojure在一段时间之前开始将所有检查过的异常包装在RTE中。你必须赶上RuntimeException,解开原因 - (.getCause e) - 检查它是否是你的异常类的instance?并根据情况处理/重新抛出。

注意:我相信最近有例外情况发生了变化,但我不清楚细节(如果你需要确切地知道发生了什么,我相信你可能想四处寻找“偷偷摸摸”) - ggroups和git日志)。 更新:参见this commit,其祖先及JIRA上的相关门票:CLJ-855: catch receives a RuntimeException rather than the expected checked exception

+1

clojure 1.4有修复使用偷偷摸摸 – gtrak 2012-04-25 10:38:17