大多数 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)))))