大多数EOF会产生有用的错误信息,例如“JSON错误(字符串中的末尾)”。但是对象和数组读取器没有处理EOF,并抛出不友好的异常。
(clojure.data.json/read-str "{")
由于read-key
中的这一行抛出错误: 字符的数值超出范围:-1
(throw (Exception. (str "JSON错误(非字符串键在对象中),找到 " (char c) ", 预期 " "\"")))
(char c)
因c为-1而抛出。
在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)))))