Question

I have this macro to catch a particularly annoying VMware bug (it goes away if you reconnect)

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

when tested in the repl it works:

(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

when the bug pops up in a real run this code :

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

falls rights through the catch

 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)
Was it helpful?

Solution

It would appear that your exception is being wrapped in a RuntimeException; Clojure started wrapping all checked exceptions in RTEs some time ago. You'll have to catch RuntimeException, unwrap the cause -- (.getCause e) -- check if it is an instance? of your exception class and handle/rethrow as appropriate.

NB. I believe some changes have been made to the exception story recently, but I don't remember the details very clearly (if you need to know exactly what's going on, I believe you might want to search around for "sneaky throw" -- on the ggroups and in the git logs). Update: see this commit, its ancestors and the related ticket on JIRA: CLJ-855: catch receives a RuntimeException rather than the expected checked exception.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top