[cl-json-devel] bug report

Boris Smilga boris.smilga at gmail.com
Sun Jun 5 21:53:20 UTC 2011


On 5 Jun 2011, at 23:47, Nicolas Martyanoff wrote:

> The following form breaks when evaluated:
>
> (json:encode-json-to-string '((:a . ((:b . ((:c . 42)))))))
>
> Help! 11 nested errors. SB-KERNEL:*MAXIMUM-ERROR-DEPTH* exceeded.

Hello.  That's expected behaviour (sort of).

Essentially, when ENCODE-JSON is passed a cons cell, it has no way of  
telling whether the cell is the head of A) an alist (which should be  
encoded as a JSON Object), or B) of a proper list which is not an  
alist (which should be encoded as a JSON Array), or C) of an improper  
list (which is unencodable and so should produce an error).  So it  
tries the option B first, and, if that fails, the option A.  In your  
case, this situation is reproduced on every level of nesting. The  
problem is that SB-KERNEL:*MAXIMUM-ERROR-DEPTH* is quite shallow by  
default (10), and the try-proper-list-fall-back-to-alist approach  
results in a layering of nested conditions which is deeper than that  
number.  Writing, e. g.,

   (let ((sb-kernel:*maximum-error-depth* 20))
     (json:encode-json-to-string '((:a . ((:b . ((:c . 42))))))))

produces the correct result, "{\"a\":{\"b\":{\"c\":42}}}" .

I know this is not a sustainable approach, but at this moment I have  
no good idea how to modify CL-JSON to get around this issue.  Your  
best options at this moment would be to use either CLOS objects  
instead of alists, or the explicit encoder from the repository version:

   (json:with-explicit-encoder
     (json:encode-json-to-string
       '(:object :a (:object :b (:object :c 42)))))

or

  (json:with-explicit-encoder
     (json:encode-json-to-string
       '(:object (:a . (:object (:b . (:object (:c . 42))))))))

Sincerely,
  - B. Smilga.





More information about the cl-json-devel mailing list