leonoel / missionary

A functional effect and streaming system for Clojure/Script
Eclipse Public License 2.0
620 stars 25 forks source link

Deref in task causing a silent Interrupted Exception #107

Closed yenda closed 2 months ago

yenda commented 3 months ago

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))
yenda commented 3 months ago

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))
leonoel commented 2 months ago

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