nlohmann / json

JSON for Modern C++
https://json.nlohmann.me
MIT License
42.97k stars 6.72k forks source link

Exception throw even though code is inside try/catch #3926

Closed paulocoutinhox closed 1 year ago

paulocoutinhox commented 1 year ago

Description

Even though my code is inside a try it is throwing exception and stopping the program.

Reproduction steps

Only need call the example function:

auto response = decodeFunctionReturnValue<std::string>("");

Expected vs. actual results

Excepted is return the default value when exception happen. Actual result is crashing.

Minimal code example

template <typename T>
static std::optional<T> decodeFunctionReturnValue(const std::string &data)
{
    try
    {
        auto j = json::parse(data);

        if (j["r"].is_null())
        {
            return std::nullopt;
        }
        else
        {
            return j["r"].template get<T>();
        }
    }
    catch (std::exception &e)
    {
        spdlog::error("[JsonSerializer : decodeFunctionReturnValue] Error when decode return value: {}", e.what());
    }

    return std::nullopt;
}

### Error messages

```Shell
"Error: nlohmann::json_abi_v3_11_2::detail::parse_error,[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
    at __cxa_throw (http://localhost:3000/@fs/Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/bin/xplpc.wasm:wasm-function[10187]:0x1806e0)
    at bool nlohmann::json_abi_v3_11_2::detail::json_sax_dom_parser<nlohmann::json_abi_v3_11_2::basic_json<std::__2::map, std::__2::vector, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, bool, long long, unsigned long long, double, std::__2::allocator, nlohmann::json_abi_v3_11_2::adl_serializer, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>>>>::parse_error<nlohmann::json_abi_v3_11_2::detail::parse_error>(unsigned long, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&, nlohmann::json_abi_v3_11_2::detail::parse_error const&) (http://localhost:3000/@fs/Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/bin/xplpc.wasm:wasm-function[1136]:0x2f2a5)
    at bool nlohmann::json_abi_v3_11_2::detail::parser<nlohmann::json_abi_v3_11_2::basic_json<std::__2::map, std::__2::vector, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, bool, long long, unsigned long long, double, std::__2::allocator, nlohmann::json_abi_v3_11_2::adl_serializer, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>>>, nlohmann::json_abi_v3_11_2::detail::iterator_input_adapter<std::__2::__wrap_iter<char const*>>>::sax_parse_internal<nlohmann::json_abi_v3_11_2::detail::json_sax_dom_parser<nlohmann::json_abi_v3_11_2::basic_json<std::__2::map, std::__2::vector, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, bool, long long, unsigned long long, double, std::__2::allocator, nlohmann::json_abi_v3_11_2::adl_serializer, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>>>>>(nlohmann::json_abi_v3_11_2::detail::json_sax_dom_parser<nlohmann::json_abi_v3_11_2::basic_json<std::__2::map, std::__2::vector, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, bool, long long, unsigned long long, double, std::__2::allocator, nlohmann::json_abi_v3_11_2::adl_serializer, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>>>>*) (http://localhost:3000/@fs/Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/bin/xplpc.wasm:wasm-function[1135]:0x2e1b6)
    at nlohmann::json_abi_v3_11_2::detail::parser<nlohmann::json_abi_v3_11_2::basic_json<std::__2::map, std::__2::vector, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, bool, long long, unsigned long long, double, std::__2::allocator, nlohmann::json_abi_v3_11_2::adl_serializer, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>>>, nlohmann::json_abi_v3_11_2::detail::iterator_input_adapter<std::__2::__wrap_iter<char const*>>>::parse(bool, nlohmann::json_abi_v3_11_2::basic_json<std::__2::map, std::__2::vector, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, bool, long long, unsigned long long, double, std::__2::allocator, nlohmann::json_abi_v3_11_2::adl_serializer, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>>>&) (http://localhost:3000/@fs/Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/bin/xplpc.wasm:wasm-function[894]:0x204a9)
    at nlohmann::json_abi_v3_11_2::basic_json<std::__2::map, std::__2::vector, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, bool, long long, unsigned long long, double, std::__2::allocator, nlohmann::json_abi_v3_11_2::adl_serializer, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>>> nlohmann::json_abi_v3_11_2::basic_json<std::__2::map, std::__2::vector, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, bool, long long, unsigned long long, double, std::__2::allocator, nlohmann::json_abi_v3_11_2::adl_serializer, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>>>::parse<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&>(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&, std::__2::function<bool (int, nlohmann::json_abi_v3_11_2::detail::parse_event_t, nlohmann::json_abi_v3_11_2::basic_json<std::__2::map, std::__2::vector, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, bool, long long, unsigned long long, double, std::__2::allocator, nlohmann::json_abi_v3_11_2::adl_serializer, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>>>&)>, bool, bool) (http://localhost:3000/@fs/Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/bin/xplpc.wasm:wasm-function[863]:0x1e426)
    at std::__2::optional<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>> xplpc::serializer::Serializer::decodeFunctionReturnValue<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>>(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&) (http://localhost:3000/@fs/Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/bin/xplpc.wasm:wasm-function[5443]:0xeaf13)


### Compiler and operating system

clang macos

### Library version

3.11.2

### Validation

- [ ] The bug also occurs if the latest version from the [`develop`](https://github.com/nlohmann/json/tree/develop) branch is used.
- [ ] I can successfully [compile and run the unit tests](https://github.com/nlohmann/json#execute-unit-tests).
gregmarr commented 1 year ago

You're catching by non-const reference. What if you catch by const reference or by value?

I see xplpc.wasm in the call stack. Is this a WebAssembly build?

paulocoutinhox commented 1 year ago

Hi @gregmarr,

Yes, it is a WebAssembly build.

I tried in a simple file in my local machine without WASM context and it compiles and run without problems:

#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main(int argc, char const *argv[])
{
    try
    {
        //auto j = json::parse(R"({"value": "demo"})");
        auto j = json::parse(R"(!)");
        std::cout << j << std::endl;

        //auto value = j["value"].get<std::string>();
        auto value = j["value"].template get<std::string>();

        std::cout << "VALUE: " << value << std::endl;
    }
    catch (std::exception &e)
    {
        std::cout << "ERROR: " << e.what() << std::endl;
    }

    return EXIT_SUCCESS;
}

// To compile with gcc:
// 1 - Need header files from https://github.com/nlohmann/json inside folder "include"
// 2 - g++ -std=c++17 -Iinclude main.cpp -o json

Can be a problem with WebAssembly only?

Thanks.

nlohmann commented 1 year ago

The exceptions of the library inherit from std::exception (see https://json.nlohmann.me/home/exceptions/), so the code looks fine. Very strange.

gregmarr commented 1 year ago

Are you using Emscripten? https://emscripten.org/docs/porting/exceptions.html

paulocoutinhox commented 1 year ago

Hi,

Yes, im using.

Im trying to compile a simple with it and always throw error.

I tried all emscripten compile flags.

paulocoutinhox commented 1 year ago

Solved now.

The problem is that i need use the flags on CXX_FLAGS too:

set(XPLPC_WASM_LINKER_FLAGS "--bind -sMALLOC=emmalloc -sWASM_BIGINT=1 -sALLOW_MEMORY_GROWTH=1 -fwasm-exceptions -sMODULARIZE=1 -sEXPORT_ES6=1")
set(XPLPC_WASM_COMPILER_FLAGS "-fwasm-exceptions")

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${XPLPC_WASM_LINKER_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${XPLPC_WASM_COMPILER_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${XPLPC_WASM_COMPILER_FLAGS}")

Thanks.

gregmarr commented 1 year ago

You're welcome. Glad you were able to sort it out.