diff --git a/frontend/src/app/main/errors.cljs b/frontend/src/app/main/errors.cljs index 205452e8d8..fe5a82518e 100644 --- a/frontend/src/app/main/errors.cljs +++ b/frontend/src/app/main/errors.cljs @@ -343,7 +343,12 @@ (= message "Possible side-effect in debug-evaluate") (= message "Unexpected end of input") (str/starts-with? message "invalid props on component") - (str/starts-with? message "Unexpected token ")))) + (str/starts-with? message "Unexpected token ") + ;; Abort errors are expected when an in-flight HTTP request is + ;; cancelled (e.g. via RxJS unsubscription / take-until). They + ;; are handled gracefully inside app.util.http/fetch and must + ;; NOT be surfaced as application errors. + (= (.-name ^js cause) "AbortError")))) (on-unhandled-error [event] (.preventDefault ^js event) diff --git a/frontend/src/app/util/http.cljs b/frontend/src/app/util/http.cljs index 0fd9be60b7..a25f030d3f 100644 --- a/frontend/src/app/util/http.cljs +++ b/frontend/src/app/util/http.cljs @@ -123,10 +123,15 @@ (/ current-time (inc count))) count (inc count)] (swap! network-averages assoc (:path uri) {:count count :average average}))))) + (fn [] (vreset! unsubscribed? true) (when @abortable? - (.abort ^js controller))))))) + ;; Provide an explicit reason so that the resulting AbortError carries + ;; a meaningful message instead of the browser default + ;; "signal is aborted without reason". + (.abort ^js controller (ex-info (str "fetch to '" uri "' is aborted") + {:uri uri})))))))) (defn response->map [response]