Welcome! Please see the About page for a little more info on how this works.

0 votes
ago in Syntax and reader by

I've noticed that clojure.edn parser will skip rest of the file if it manages to find the first valid token that will complete collection. For example:

;; demo.edn
{
 :foo 1
 :bar 2 }
 :baz 3 
}

with:

(require '[clojure.edn :as edn]
         '[clojure.java.io :as io])

(with-open [r (io/reader "demo.edn")]
  (edn/read (java.io.PushbackReader. r)))

user=> {:foo 1, :bar 2}

It will also ignore rest of the file when the file is clearly malformed:

{
 :foo 1
 :bar 2 }
xxxx yyyy }}}}} {{{{ ((
 :baz 3 

it returns again:

user=> {:foo 1, :bar 2}

I was expecting it to throw EOF exception or at least '}' mismatch. Is this behavior by design or a possible bug?

1 Answer

+2 votes
ago by
selected ago by
 
Best answer

It's by design, all according to the docstring of edn/read:

Reads the next object from stream [...]

You can read multiple times from the same stream to get all of the objects and to validate the whole file.

(with-open [r (io/reader "demo.edn")]
  (loop []
    (let [data (edn/read (java.io.PushbackReader. r))]
      (println "Got data" data)
      (recur))))
Got data {:foo 1, :bar 2}
Got data :baz
Got data 3
Execution error at user/eval3609 (form-init10153318817371430115.clj:3).
Unmatched delimiter: }
ago by
Yeah, I've overlooked that part in docstring :D Thanks!
...