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

Error type and config handling #1416

Merged
merged 12 commits into from
Jan 14, 2019

Conversation

cryptocode
Copy link
Contributor

@cryptocode cryptocode commented Nov 30, 2018

New error type

As mentioned in issue #1111, users should get useful information when there's a config error. This PR introduces a nano::error type that wraps a std::error_code along with a custom error string.

It's able to consume bool error flags, std::error_code, boost::system::error_code and std::exception (all of which are used in the code base). It should be a good alternative in cases where dynamic error messages are required or when multiple types of errors must be handled (exceptions, bools, boost ec etc).

The nano::error type has some documentation here (I'll expand it) https://github.com/cryptocode/notes/wiki/Error-handling

std::error_code should still be used in most situations, and nano::error is able to convert to and from it.

JSON config abstraction

A nano::jsonconfig wrapper around boost's ptree is added. It uses nano::error to communicate error messages, which are for the most part automatically constructed from key name and type information. So if you're reading a port number of type uint16_t and the config contains an invalid value, you'll get "Error deserializing config: port is not an integer between 0 and 65535"

In addition to automated messages, range checks and so on are given a descriptive error, such as "At least one representative account must be set"

nano::jsonconfig should make it easier to eventually move the config to a proper JSON parser.

EDIT: pr is ready for review

@cryptocode cryptocode added the incomplete This item is incomplete and should not be merged if it is a pull request label Nov 30, 2018
@cryptocode cryptocode self-assigned this Nov 30, 2018
@cryptocode cryptocode removed the incomplete This item is incomplete and should not be merged if it is a pull request label Dec 1, 2018
@rkeene rkeene added this to the V18.0 milestone Dec 8, 2018
@cryptocode cryptocode force-pushed the config-error-handling branch 2 times, most recently from 90d4b75 to 1f82fb9 Compare December 22, 2018 13:14
@cryptocode
Copy link
Contributor Author

cryptocode commented Dec 22, 2018

@wezrule seems like some commit comments got removed when I amended by mistake.

What I was saying was that constexpr will (on gcc) produce

enclosing class of constexpr non-static member function is not a literal type constexpr int json_version () const, i.e. constructor is not constexpr.

So inline is what seems to work across the board. C++ inline variables will be perfect for this I think.

@wezrule
Copy link
Contributor

wezrule commented Dec 23, 2018

@cryptocode No worries. For anyone else reading, I originally commented on 1f82fb9 querying why constexpr was removed instead of inline (as inline is implicit with constexpr) as I thought that's what the warning was about originally, but it was a misguided assumption.

I tried this in compiler explorer (with c++14 compiler option):

class C {
  C();
  constexpr int f() { return 0; }
};

It only appears legal with versions gcc 7.2/clang 3.6 and greater. Curious, I did some more research and it looks like it was an oversight in the original spec to not allow constexpr static/non-static member functions of non-literal classes which has since been rectified:
https://groups.google.com/a/isocpp.org/forum/embed/#!topic/std-discussion/6jM8M8FUs30

So for greater C++14 compiler support not using them is beneficial (more reason to get #1044 done 👍). Although I'm not entirely sure why it was changed from a static constexpr variable to begin with, was this related to compiler support as well? I don't want to dwell too much on these minor details (there's plenty of better things to be doing!), but I will just add that member functions defined inside a class body are already implicitly inlined, so using the inline specifier is redundant.

@cryptocode
Copy link
Contributor Author

cryptocode commented Dec 23, 2018

@wezrule IIRC static constexpr ran into ODR-used issue in one instance (on some compiler) - something that's apparently fixed in C++17.

Removed the superfluous inline specifier (I have other PRs with it as well; old habit. I'll update them later)

Copy link
Contributor

@wezrule wezrule left a comment

Choose a reason for hiding this comment

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

Tested a few different errors in config.json and works fab!
I guess the next step is to have a gui for this to stop hand-written problems altogether!

@cryptocode cryptocode force-pushed the config-error-handling branch from 69a2c41 to 4bbaf59 Compare January 9, 2019 18:08
@cryptocode
Copy link
Contributor Author

cryptocode commented Jan 10, 2019

@wezrule

So I think you can remove all the user defined constructors because they will be auto generated for you doing the same. If not then they can at least be = default.

Removing didn't compile on clang, but they can probably be defaulted. I'll look into it again.

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

Successfully merging this pull request may close these issues.

4 participants