Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert deserializers to use exceptions #1584

Merged

Conversation

wezrule
Copy link
Contributor

@wezrule wezrule commented Jan 14, 2019

While working on Issue #1374 I have to (de)serialize a new object type which had a few member variables. While looking at the existing serialization functions to the data store I thought it would be more readable to use exceptions. It turns something like this:

auto error (read (stream_a, min_hash));
if (!error)	
{	
	error= read (stream_a, max_hash);	
	if (!error)
	{	
		error= read (stream_a, mode);	
                if (!error)
                {
                    error = read (stream_a, max_count);
                }
	}	
}	
return error;

Into:

auto error (false);
try
{
	nano::read (stream_a, min_hash);
	nano::read (stream_a, max_hash);
	nano::read (stream_a, mode);
	nano::read (stream_a, max_count);
}
catch (std::runtime_error const &)
{
	error = true;
}

return error;

The previous (existing) form doesn't scale well, some places have 6 members and it's not unfeasible to expect some to have many more in the future. It is in my opinion much more readable and looks more like the serializing functions:

nano::write (stream_a, min_hash);
nano::write (stream_a, max_hash);
nano::write (stream_a, mode);
nano::write (stream_a, max_count);

So it is much easier to spot mistakes. In an ideal world the exceptions wouldn't be handled as low level here and instead much higher up the stack, so it could look even cleaner however as deserializer functions return a boolean and there are many of them which would need changing I have left this for now to reduce the risk of regression.

A few things were done:

  • The innards of nano::read have been put into a new function called nano::try_read. This follows a convention in .NET which uses try_* prefixes which return a boolean indicating success/failure and the normal function throws an exception as we still need both and it was a nice way to differentiate them. Boost also has try_lexical_convert which returns a boolean while lexical_cast throws. In a previous commit I created my own exception type (deserialization_error) and also std::cerr'ed any exceptions. However this is too low level, so gets output in tests for instance so I am just keeping it has it currently is.
  • All serialize functions now proceed deserialize in both header and source files, to keep things consistent.
  • If there are json equivalents these are now kept together
  • In lmdb.cpp nano::mdb_val::operator std::array<char, 64> () const demonstrates that returning errors can be happily ignored, something that doesn't happen with exceptions. In c++17 there is the [[no_discard]] attribute however but this cannot be used yet. core/test/network.cpp also checks the returned error condition now.

@wezrule wezrule added the quality improvements This item indicates the need for or supplies changes that improve maintainability label Jan 14, 2019
@zhyatt zhyatt requested a review from cryptocode January 14, 2019 12:44
@zhyatt zhyatt requested a review from clemahieu January 14, 2019 12:49
Copy link
Contributor

@cryptocode cryptocode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving code pending rebase, though the question is if we want to introduce exception handling as the code base is currently error code based.

@zhyatt zhyatt added this to the V18.0 milestone Jan 28, 2019
@wezrule wezrule force-pushed the convert_deserialization_to_use_exceptions branch from 1ec53bd to 7270b4f Compare January 29, 2019 13:28
@wezrule wezrule merged commit 3ddee7c into nanocurrency:master Feb 5, 2019
@wezrule wezrule deleted the convert_deserialization_to_use_exceptions branch February 5, 2019 15:57
argakiig pushed a commit that referenced this pull request Feb 5, 2019
* Initial changes

* Bit of cleanup and formatting

* More formatting

* See if including the boost file directly, fixes build on travis

* Remove new exception type and spitting out exception details

* Constructors with hashables should check for errors as before

* Error condition incorrect

* Add changes to confirm_req::deserialization
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
quality improvements This item indicates the need for or supplies changes that improve maintainability
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants