Skip to content

json::parse(allow_exceptions = false) documentation is misleading. #2360

Closed
@TobiSchluter

Description

@TobiSchluter

What is the issue you have?

I'm a fan of the library and I try to update my code to new options / features regularly. This is a shortcoming of the documentation.

This time I ran into very weird bugs when I changed my security checks from using exceptions to the new form

if (auto jFile = nlohmann::json::parse(std::ifstream{ configPath }, nullptr, false)
            ; jFile == nlohmann::json::value_t::discarded) {
    /// Error, bad json in file
}

(i.e. using allow_exceptions = false). I tried to follow the documentation, which describes the return value as follows:

Deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded.

If the return value "is" something, then my understanding was that one can compare to it (this seemed a bit surprising but very much unambiguous). Turns out this doesn't work. operator== in the if-condition is resolved to

    template<typename ScalarType, typename std::enable_if<
                 std::is_scalar<ScalarType>::value, int>::type = 0>
    friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
    {
        return lhs == basic_json(rhs);
    }

which as you can see wraps the rhs into a basic_json object, so my comparison is never going to yield equality.

Searching through the documentation for "discarded" I found is_discarded() which does the right thing, but whose documentation is woefully out of date:

This function will always be false for JSON values after parsing.
That is, discarded values can only occur during parsing, but will be
removed when inside a structured value or replaced by null in other cases.

This clearly isn't in line with what parse() does.

Please describe the steps to reproduce the issue.

An example would be

#include <nlohmann/json.hpp> 
auto j = nlohmann::json::parse("adsg", nullptr, false);
if (j != nlohmann::json::value_t::discarded)
    std::cerr << "I didn't understand the docs.\n";

// A compile error would be ideal. These implicit conversions are really confusing.
// I don't believe it can break user code for "value_t::discarded".

Which version of the library did you use?

  • latest release version 3.9.1
  • other release - please state the version: ___
  • the develop branch

I also checked the online docs.

Metadata

Metadata

Assignees

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions