JSON.jl icon indicating copy to clipboard operation
JSON.jl copied to clipboard

Unexpected end of input error when parsing input streams

Open julbinb opened this issue 4 years ago • 9 comments

When parsing JSON values from an input stream like this

using JSON

while !eof(stdin)
  JSON.parse(stdin)
end

depending on the type of a value in the input, parsing either succeeds or fails.

For example, if the code above is in parse.jl, and file 1.in contains just 5 (no spaces before or after the number), this works:

$ julia parse.jl < 1.in

But if 2.in contains [5] instead (no spaces before or after the list), then there is an error:

$ julia parse.jl < 2.in
ERROR: LoadError: Unexpected end of input
 ...when parsing byte with value '10'

julbinb avatar Sep 16 '20 15:09 julbinb

A minimal working example is simply

using JSON
JSON.parse("")
ERROR: Unexpected end of input
Line: 0
Around: ......
           ^

JSON.parse("5"), JSON.parse("[5]"), JSON.parse("[]"), JSON.parse("{}") and similar inputs seem to work as expected. Perhaps an empty string should return nothing rather than throwing an exception as it is not invalid JSON.

martinkjlarsson avatar Jan 19 '21 17:01 martinkjlarsson

Perhaps an empty string should return nothing rather than throwing an exception as it is not invalid JSON.

What makes you say it is valid JSON? Also, returning nothing seems odd to me since that is not a json value.

KristofferC avatar Jan 19 '21 18:01 KristofferC

I was too hasty with commenting. An empty string is not valid JSON and the current behavior seems to be correct. My bad.

martinkjlarsson avatar Jan 19 '21 19:01 martinkjlarsson

I am having a similar issue.

#  This works fine
JSON.parse("123") 

# This errors with "Unexpected end of input"
JSON.parse(IOBuffer("123"))

wardlem avatar May 07 '21 13:05 wardlem

Curiously,

JSON.parse(IOBuffer("123\n"))

works just fine.

wardlem avatar May 07 '21 13:05 wardlem

Maybe https://github.com/JuliaIO/JSON.jl/blob/1c24980c320842e17720c173be767c161f36feb9/src/Parser.jl#L108 needs an eof check.

KristofferC avatar May 07 '21 14:05 KristofferC

Created #321 for this.

wardlem avatar May 07 '21 14:05 wardlem

Related to the above, I just wanted to comment that the current error message for the very simple reproducer is not helpful:

julia> using JSON

julia> JSON.parse("")
ERROR: Unexpected end of input
Line: 0
Around: ......
           ^

Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:33
 [2] _error(message::String, ps::JSON.Parser.MemoryParserState)
   @ JSON.Parser ~/.julia/packages/JSON/QXB8U/src/Parser.jl:140
 [3] byteat
   @ ~/.julia/packages/JSON/QXB8U/src/Parser.jl:49 [inlined]
 [4] parse_value(pc::JSON.Parser.ParserContext{Dict{String, Any}, Int64, true, nothing}, ps::JSON.Parser.MemoryParserState)
 [5] parse(str::String; dicttype::Type, inttype::Type{Int64}, allownan::Bool, null::Nothing)
   @ JSON.Parser ~/.julia/packages/JSON/QXB8U/src/Parser.jl:450
 [6] parse(str::String)
   @ JSON.Parser ~/.julia/packages/JSON/QXB8U/src/Parser.jl:448

We saw this error message in the wild, and it wasn't at all clear to me what it was indicating. My two requests for improvement:

  1. Could the error message indicate that the error happened when attempting to parse json? (ERROR: Failed to parse JSON: Unexpected end of input)
  2. It was not at all clear to me from the message that the problem was that the data was empty. Could we fix whatever is going wrong with the Around: ......, so that it showed the empty string? Something like this instead?:
    Line: 0
    Around: ""
            ^
    

NHDaly avatar Jan 11 '22 21:01 NHDaly

Should you not export this function to access this?

export

X3Coyote avatar Mar 14 '24 21:03 X3Coyote