leonoel/missionary

Deref in task causing a silent Interrupted Exception

Closed this issue · 2 comments

Even if the exception is caught and the deref is in the catch:

(defn task []
  (m/sp
    (try
      (m/? (m/reduce
            (constantly nil)
            (m/ap (let [s (m/?> (m/seed [1 2 3]))]
                    (m/? (m/via m/blk (throw (ex-info "BOOM" {}))))))))
      (catch Exception e
        (println "Catching the exception")
        @(future (println "Printing in future"))
        (println "Never prints")))))

((task) (constantly nil) (constantly nil))

while:

(defn task []
  (m/sp
    (m/? (m/reduce
          (constantly nil)
          (m/ap (let [s (m/?> (m/seed [1 2 3]))]
                  (m/? (m/via m/blk (println s)))))))
    @(future (println "Printing in future"))
    (println "Does prints")))

((task) (constantly nil) (constantly nil))

Adding this snippet as well, deref works outside the catch:

((m/sp
   (try
     (m/? (m/reduce
           (constantly nil)
           (m/ap (let [s (m/?> (m/seed [1 2 3]))]
                   (m/? (m/via m/blk (throw (ex-info "BOOM" {}))))))))
     (catch Exception e
       (println "Catching the exception")
       (try
         @(future (println "Printing in future"))
         (catch Exception _
           (println "The deref blew up but we catch it")))
       (println "This would never print without catching the exception from deref")))
   @(future (println "Printing in future outside catch"))
   (println "And this prints because the deref above doesn't blow up"))
 (constantly nil) (constantly nil))

Fixed in b.37. via continuations are now called after clearing the interruption flag, such that interruptible user code is not interrupted.