大多数EOFs会产生有用的错误信息,例如JSON错误(字符串中的文件结束符)
。但是对象和数组读取器不处理EOF,并抛出无用的异常。
(clojure.data.json/read-str "{")
由于在read-key
中的这一行抛出char的值超出范围:-1
(throw (Exception. (str "JSON错误(对象中的非字符串键),找到 "
(char c) ",期望 "
\"\")")))
当c为-1时,(char c)
会抛出异常。
通过在read-key中处理-1情况来解决这个问题
(defn- read-key [^PushbackReader stream]
(let [c (int (next-token stream))]
(if (= c (codepoint \"))
(let [key (read-quoted-string stream)]
(if (= (codepoint \:) (int (next-token stream)))
key
(throw (Exception. "JSON error (missing `:` in object)"))))
(codepoint-case c
\} nil
-1 (throw (Exception. "JSON error (end-of-file inside object)"))
(throw (Exception. (str "JSON error (non-string key in object), found `" (char c) "`, expected `\"`")))))))
(clojure.data.json/read-str "{\"\":\"\"")
给出错误的错误信息:JSON错误(对象中缺少条目)
通过在read-object中处理EOF来解决这个问题
(codepoint-case (int (next-token stream))
\, (recur r)
\} (persistent! r)
-1 (throw (Exception. "JSON error (end-of-file inside object)"))
(throw (Exception. "JSON error (missing entry in object)"))))
(clojure.data.json/read-str "[")
抛出JSON错误(意外的字符):
(意外的字符是(char 65535))。这是因为read-array
将-1推回流中,而-1被推为65535。
修复方法是处理read-array中的EOF
(defn- read-array [^PushbackReader stream options]
;; Expects to be called with the head of the stream AFTER the
;; opening bracket.
;; Only handles array value.
(let [c (int (next-token stream))]
(codepoint-case c
\] []
\, (throw (invalid-array-exception))
-1 (throw (Exception. "JSON error (end-of-file inside array)"))
(do (.unread stream c)
(read-array* stream options)))))