🐛 Add error handling for image fetching in backend

This commit is contained in:
Andrey Antukh 2026-03-09 17:47:34 +01:00
parent 05c71f7b75
commit ab6faa2c0a
2 changed files with 58 additions and 3 deletions

View File

@ -30,7 +30,12 @@
[datoteka.io :as io])
(:import
clojure.lang.XMLHandler
java.io.IOException
java.io.InputStream
java.net.ConnectException
java.net.UnknownHostException
java.net.http.HttpConnectTimeoutException
java.net.http.HttpTimeoutException
javax.xml.XMLConstants
javax.xml.parsers.SAXParserFactory
org.apache.commons.io.IOUtils
@ -318,9 +323,37 @@
{:size size :mtype mtype :format format}))]
(let [{:keys [body] :as response} (http/req! client
{:method :get :uri uri}
{:response-type :input-stream})
(let [{:keys [body] :as response}
(try
(http/req! client
{:method :get :uri uri}
{:response-type :input-stream})
(catch ConnectException cause
(ex/raise :type :validation
:code :unable-to-access-to-url
:hint "the url is unreachable or the connection was refused"
:cause cause))
(catch UnknownHostException cause
(ex/raise :type :validation
:code :unable-to-access-to-url
:hint "the url host cannot be resolved"
:cause cause))
(catch HttpConnectTimeoutException cause
(ex/raise :type :validation
:code :unable-to-access-to-url
:hint "the url connection timed out"
:cause cause))
(catch HttpTimeoutException cause
(ex/raise :type :validation
:code :unable-to-access-to-url
:hint "the url request timed out"
:cause cause))
(catch IOException cause
(ex/raise :type :validation
:code :unable-to-access-to-url
:hint "an I/O error occurred while downloading the url"
:cause cause)))
{:keys [size mtype]} (parse-and-validate response)
path (tmp/tempfile :prefix "penpot.media.download.")
written (io/write* path body :size size)]

View File

@ -248,6 +248,28 @@
(t/is (uuid? (:thumbnail-id result))))))
(t/deftest media-object-from-url-command-when-url-is-unreachable
(let [prof (th/create-profile* 1)
proj (th/create-project* 1 {:profile-id (:id prof)
:team-id (:default-team-id prof)})
file (th/create-file* 1 {:profile-id (:id prof)
:project-id (:default-project-id prof)
:is-shared false})
;; Use a URL that is guaranteed to be unreachable from the backend
url "http://192.0.2.1/image.png"
params {::th/type :create-file-media-object-from-url
::rpc/profile-id (:id prof)
:file-id (:id file)
:is-local true
:url url}
out (th/command! params)]
(let [error (:error out)
error-data (ex-data error)]
(t/is (th/ex-info? error))
(t/is (= :validation (:type error-data)))
(t/is (= :unable-to-access-to-url (:code error-data))))))
(t/deftest media-object-upload-command-when-file-is-deleted
(let [prof (th/create-profile* 1)
proj (th/create-project* 1 {:profile-id (:id prof)