1

我有这个宏来捕捉一个特别烦人的 VMware 错误(如果你重新连接它就会消失)

(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
          ~@body
          (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

当错误在实际运行中弹出此代码时:

(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)
4

1 回答 1

5

看来您的异常被包裹在RuntimeException; Clojure 不久前开始在 RTE 中包装所有已检查的异常。你必须抓住RuntimeException,解开原因——(.getCause e)检查它是否是instance?你的异常类,并酌情处理/重新抛出。

注意。我相信最近对异常故事进行了一些更改,但是我不太清楚地记得细节(如果您需要确切地知道发生了什么,我相信您可能想四处搜索“偷偷摸摸”-on ggroups 和 git 日志中)。更新:在 JIRA 上查看此提交、其祖先和相关票证:CLJ-855:catch 收到 RuntimeException 而不是预期的检查异常

于 2012-04-25T01:59:07.343 回答