Skip to content

Add support of nullable fields to NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE and NLOHMANN_DEFINE_TYPE_INTRUSIVE #2356

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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