[BREAKING] Standardize :nippy/_ response forms

This commit is contained in:
Peter Taoussanis 2020-09-10 12:08:28 +02:00
parent b4b5450d97
commit 25706d09d5
2 changed files with 51 additions and 34 deletions

View file

@ -34,8 +34,6 @@
(thaw (freeze stress-data))) (thaw (freeze stress-data)))
;;;; TODO ;;;; TODO
;; - Ensure all error responses are entirely under {:nippy/_ <...>} key?
;;; Would be a nice change, but breaking.
;; - Performance would benefit from ^:static support / direct linking / etc. ;; - Performance would benefit from ^:static support / direct linking / etc.
;; - Ability to compile out metadata support? ;; - Ability to compile out metadata support?
;; - Auto cache keywords? When map keys? Configurable? Per-map ;; - Auto cache keywords? When map keys? Configurable? Per-map
@ -892,19 +890,22 @@
(catch Throwable _ (catch Throwable _
(try (try
(str x) (str x)
(catch Throwable _ :nippy/unprintable))))) (catch Throwable _
:nippy/unprintable)))))
(defn write-unfreezable [out x] (defn write-unfreezable [out x]
(-freeze-without-meta! (-freeze-without-meta!
{:type (type x) {:nippy/unfreezable
:nippy/unfreezable (try-pr-edn x)} {:type (type x)
:content (try-pr-edn x)}}
out)) out))
(defn throw-unfreezable [x] (defn throw-unfreezable [x]
(throw (let [t (type x)]
(ex-info (str "Unfreezable type: " (type x)) (throw
{:type (type x) (ex-info (str "Unfreezable type: " t)
:as-str (try-pr-edn x)}))) {:type t
:as-str (try-pr-edn x)}))))
;; Public `-freeze-with-meta!` with different arg order ;; Public `-freeze-with-meta!` with different arg order
(defn freeze-to-out! (defn freeze-to-out!
@ -1336,9 +1337,12 @@
(try (try
(enc/read-edn {:readers *data-readers*} edn) (enc/read-edn {:readers *data-readers*} edn)
(catch Exception e (catch Exception e
{:type :reader {:nippy/unthawable
:throwable e {:type :reader
:nippy/unthawable edn}))) :cause :exception
:content edn
:exception e}})))
(defn- read-object [^DataInput in class-name] (defn- read-object [^DataInput in class-name]
(try (try
@ -1346,18 +1350,22 @@
(try (try
(let [class (Class/forName class-name)] (cast class content)) (let [class (Class/forName class-name)] (cast class content))
(catch Exception e (catch Exception e
{:type :serializable {:nippy/unthawable
:throwable e {:type :serializable
:nippy/unthawable :cause :exception
{:class-name class-name :content content
:serializable-whitelist-pass? true}}))) :class-name class-name
:content content
:exception e}})))
(catch Exception e (catch Exception e
{:type :serializable {:nippy/unthawable
:throwable e {:type :serializable
:nippy/unthawable :cause :exception
{:class-name class-name :content nil
:serializable-whitelist-pass? true}}))) :class-name class-name
:content nil
:exception e}})))
(defn- read-serializable-q (defn- read-serializable-q
"Quarantined => object serialized to ba, then ba written to output stream. "Quarantined => object serialized to ba, then ba written to output stream.
@ -1366,10 +1374,12 @@
(let [quarantined-ba (read-bytes in)] (let [quarantined-ba (read-bytes in)]
(if (serializable-whitelisted? class-name) (if (serializable-whitelisted? class-name)
(read-object (DataInputStream. (ByteArrayInputStream. quarantined-ba)) class-name) (read-object (DataInputStream. (ByteArrayInputStream. quarantined-ba)) class-name)
{:type :serializable {:nippy/unthawable
:nippy/unthawable {:type :serializable
{:class-name class-name :content quarantined-ba :cause :quarantined
:serializable-whitelist-pass? false}})))
:class-name class-name
:content quarantined-ba}})))
(defn- read-serializable-uq (defn- read-serializable-uq
"Unquarantined => object serialized directly to output stream. "Unquarantined => object serialized directly to output stream.
@ -1388,9 +1398,13 @@
method (.getMethod class "create" class-method-sig)] method (.getMethod class "create" class-method-sig)]
(.invoke method class (into-array Object [content]))) (.invoke method class (into-array Object [content])))
(catch Exception e (catch Exception e
{:type :record {:nippy/unthawable
:throwable e {:type :record
:nippy/unthawable {:class-name class-name :content content}})))) :cause :exception
:class-name class-name
:content content
:exception e}}))))
(defn- read-type [in class-name] (defn- read-type [in class-name]
(try (try
@ -1412,9 +1426,12 @@
(.newInstance ctor cvalues))) (.newInstance ctor cvalues)))
(catch Exception e (catch Exception e
{:type :type {:nippy/unthawable
:throwable e {:type :type
:nippy/unthawable {:class-name class-name}}))) :cause :exception
:class-name class-name
:exception e}})))
(defn thaw-from-in! (defn thaw-from-in!
"Deserializes a frozen object from given DataInput to its original Clojure "Deserializes a frozen object from given DataInput to its original Clojure

View file

@ -276,13 +276,13 @@
"Can freeze and thaw Serializable object if approved by whitelist") "Can freeze and thaw Serializable object if approved by whitelist")
(is (is
(false? (= :quarantined
(get-in (get-in
(binding [nippy/*serializable-whitelist* #{}] (binding [nippy/*serializable-whitelist* #{}]
(nippy/thaw (nippy/thaw
(binding [nippy/*serializable-whitelist* "*"] (binding [nippy/*serializable-whitelist* "*"]
(nippy/freeze (java.util.concurrent.Semaphore. 1))))) (nippy/freeze (java.util.concurrent.Semaphore. 1)))))
[:nippy/unthawable :serializable-whitelist-pass?])) [:nippy/unthawable :cause]))
"Thaw will quarantine Serializable objects approved when freezing.") "Thaw will quarantine Serializable objects approved when freezing.")