Skip to content

Add support of nullable fields to NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE and NLOHMANN_DEFINE_TYPE_INTRUSIVE #2356

@Kotodevochka

Description

@Kotodevochka

What is the issue you have?

When I try to deserialize JSON which contains nullable string fields into an object with (de)serializers generated by NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE macro, the program throws an exception at this point:

from_json.hpp line 80
error:
Exception thrown at 0x764A4DBD in TrelloBackup.exe: Microsoft C++ exception: nlohmann::detail::type_error at memory location 0x00FAE7B8.
Unhandled exception at 0x764A4DBD in TrelloBackup.exe: Microsoft C++ exception: nlohmann::detail::type_error at memory location 0x00FAE7B8.

Exception thrown: read access violation.
_Right was nullptr.

Please describe the steps to reproduce the issue.

Create a json like this:

{
      "cover":{
         "idAttachment":null,
         "color":null,
         "idUploadedBackground":null,
         "size":"normal",
         "brightness":"light"
      }
}

Define classes like this:

#pragma once

#include <string>
#include <vector>
#include <nlohmann/json.hpp>

using namespace std;
using json = nlohmann::json;

namespace TrelloDtos {

	class CoverDto {
	public:
		string idAttachment;
		string size;
	};

	class CardDto {
	public:
		CoverDto cover;
	};
		NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CoverDto, idAttachment, size)
		NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CardDto, cover)
}

Then try to deserialize:


voidTrelloApi::findCards(string response) {
    json jsonObj = json::parse(response);
    CardDto cardDto = jsonObj .get<CardDto>(); <--- at this point the exception is thrown
}

I had to write custom (de)serailizers to handle nullable fields like this:

void TrelloDtos::to_json(json& j, const CoverDto& p) {
	j = json{ {"idAttachment", p.idAttachment},{"size", p.size} };
}

void TrelloDtos::from_json(const json& j, CoverDto& p) {
	auto idAttachment = j.at("idAttachment");
	if (!idAttachment.is_null()) {
		idAttachment.get_to(p.idAttachment);
	}
	auto size = j.at("size");
	if (!size.is_null()) {
		size.get_to(p.size);
	}
}

What is the expected behavior?

I would expect the logic generated by macros not to crash if it stumbles upon a nullable field, but set nullpointr or some default value to the field.

And what is the actual behavior instead?

Exception is thrown.

Which compiler and operating system are you using?

  • Compiler: Win32
  • Operating system: Windows 8.1

Which version of the library did you use?

  • latest release version 3.9.1

If you experience a compilation error: can you compile and run the unit tests?

  • yes
  • no - please copy/paste the error message below

Metadata

Metadata

Assignees

No one assigned

    Labels

    state: please discussplease discuss the issue or vote for your favorite optionstate: stalethe issue has not been updated in a while and will be closed automatically soon unless it is updated

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions