Clojure

proxy-super does not restore original binding if call throws exception

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: Release 1.1, Release 1.2, Release 1.3, Release 1.5
  • Fix Version/s: Release 1.6
  • Component/s: None
  • Labels:
  • Patch:
    Code and Test
  • Approval:
    Ok

Description

The code for proxy-call-with-super internally used by proxy-super does not handle exceptions from the call method:

(defn proxy-call-with-super [call this meth]
 (let [m (proxy-mappings this)]
    (update-proxy this (assoc m meth nil))
    (let [ret (call)]
      (update-proxy this m)
      ret)))

As a result the following sequence behaves unexpectedly:

(def obj (proxy [java.lang.ClassLoader] []
		      (loadClass [cl] (println "enter")
				 (proxy-super loadClass cl))))
(.loadClass obj "nonexistent")
;; prints enter, then throws ClassNotFoundException
(.loadClass obj "nonexistent")
;; does not print anything before throwing cnfe

Patch: clj-983-2.patch

Approach: Use a try-finally block around the invocation to perform the after invocation action regardless of exceptions.

Screened by: Stuart Sierra

  1. clj-983-2.patch
    06/Jan/14 3:06 PM
    2 kB
    Alex Miller
  2. proxy_super.patch
    05/May/12 9:04 AM
    2 kB
    Valentin Mahrwald

Activity

People

Vote (4)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: