std::variant for error types [on hold]











up vote
-2
down vote

favorite












I'm currently in the process of rewritting a http-client class. When it comes to the error-handling I see the three options:




  1. Throwing an exception

  2. Passing an error-type by reference

  3. Returning a std::variant<SuccessType, ErrorType>


Given the following success / error types



struct HttpSuccess {
int status;
std::string body;
};
struct HttpError {
std::string error_description;
};


The function signatures for each of the three cases would look roughly like the following





  1. HttpSuccess get(const std::string& uri); (HttpErrror would inerhit from an exception type in this case)


  2. HttpSuccess get(const std::string& uri, HttpError& error) (also std::optional<HttpError>& error possible)

  3. std::variant<HttpSuccess, HttpError> get(const std::string& uri)


Here is my reasoning why I dislike option 1 + 2:




  1. Since errors are to be expected (timeouts, internet hiccups etc), I don't want to use 1. The errors the client is dealing with are no execptions semantically.

  2. There is for me no way to ensure that the error-type is properly queried (afaik google uses rules to ensure this behaviour). So users might skip the error and proceed with the garabge return type.


This reasoning alone leaves me with option 3. The upsides that I see are the following:




  1. I can introduce different error categories easily (failure to contact the a server might be represented by a different error type than a server response error e.g.)

  2. Enforces error checking (with an admitably somewhat akward use of std::visit) but establishes reasoning about the error behaviour

  3. Allows for HttpSuccess to be non-default constructible which might be relevant in cases where a complex server response is deserialized before passing it on to the client.


The downsides that I see are mainly:




  1. More complex code on the library consumer side

  2. Overhead in the non-error case due to variant wrapper




However, all-in-all the third approach feels quite unidiomatic. Are there any opinions by the experts on whether any of the approaches is superior to the others?










share|improve this question









New contributor




user823255 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











put on hold as off-topic by Ludisposed, 200_success, Toby Speight, tinstaafl, Incomputable 2 days ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Ludisposed, 200_success, Toby Speight, tinstaafl, Incomputable

If this question can be reworded to fit the rules in the help center, please edit the question.









  • 1




    I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. The example code that you have posted is not reviewable in this form because it leaves us guessing at your intentions. Unlike Stack Overflow, Code Review needs to look at concrete code in a real context. Please see Why is hypothetical example code off-topic for CR?
    – Calak
    2 days ago















up vote
-2
down vote

favorite












I'm currently in the process of rewritting a http-client class. When it comes to the error-handling I see the three options:




  1. Throwing an exception

  2. Passing an error-type by reference

  3. Returning a std::variant<SuccessType, ErrorType>


Given the following success / error types



struct HttpSuccess {
int status;
std::string body;
};
struct HttpError {
std::string error_description;
};


The function signatures for each of the three cases would look roughly like the following





  1. HttpSuccess get(const std::string& uri); (HttpErrror would inerhit from an exception type in this case)


  2. HttpSuccess get(const std::string& uri, HttpError& error) (also std::optional<HttpError>& error possible)

  3. std::variant<HttpSuccess, HttpError> get(const std::string& uri)


Here is my reasoning why I dislike option 1 + 2:




  1. Since errors are to be expected (timeouts, internet hiccups etc), I don't want to use 1. The errors the client is dealing with are no execptions semantically.

  2. There is for me no way to ensure that the error-type is properly queried (afaik google uses rules to ensure this behaviour). So users might skip the error and proceed with the garabge return type.


This reasoning alone leaves me with option 3. The upsides that I see are the following:




  1. I can introduce different error categories easily (failure to contact the a server might be represented by a different error type than a server response error e.g.)

  2. Enforces error checking (with an admitably somewhat akward use of std::visit) but establishes reasoning about the error behaviour

  3. Allows for HttpSuccess to be non-default constructible which might be relevant in cases where a complex server response is deserialized before passing it on to the client.


The downsides that I see are mainly:




  1. More complex code on the library consumer side

  2. Overhead in the non-error case due to variant wrapper




However, all-in-all the third approach feels quite unidiomatic. Are there any opinions by the experts on whether any of the approaches is superior to the others?










share|improve this question









New contributor




user823255 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











put on hold as off-topic by Ludisposed, 200_success, Toby Speight, tinstaafl, Incomputable 2 days ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Ludisposed, 200_success, Toby Speight, tinstaafl, Incomputable

If this question can be reworded to fit the rules in the help center, please edit the question.









  • 1




    I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. The example code that you have posted is not reviewable in this form because it leaves us guessing at your intentions. Unlike Stack Overflow, Code Review needs to look at concrete code in a real context. Please see Why is hypothetical example code off-topic for CR?
    – Calak
    2 days ago













up vote
-2
down vote

favorite









up vote
-2
down vote

favorite











I'm currently in the process of rewritting a http-client class. When it comes to the error-handling I see the three options:




  1. Throwing an exception

  2. Passing an error-type by reference

  3. Returning a std::variant<SuccessType, ErrorType>


Given the following success / error types



struct HttpSuccess {
int status;
std::string body;
};
struct HttpError {
std::string error_description;
};


The function signatures for each of the three cases would look roughly like the following





  1. HttpSuccess get(const std::string& uri); (HttpErrror would inerhit from an exception type in this case)


  2. HttpSuccess get(const std::string& uri, HttpError& error) (also std::optional<HttpError>& error possible)

  3. std::variant<HttpSuccess, HttpError> get(const std::string& uri)


Here is my reasoning why I dislike option 1 + 2:




  1. Since errors are to be expected (timeouts, internet hiccups etc), I don't want to use 1. The errors the client is dealing with are no execptions semantically.

  2. There is for me no way to ensure that the error-type is properly queried (afaik google uses rules to ensure this behaviour). So users might skip the error and proceed with the garabge return type.


This reasoning alone leaves me with option 3. The upsides that I see are the following:




  1. I can introduce different error categories easily (failure to contact the a server might be represented by a different error type than a server response error e.g.)

  2. Enforces error checking (with an admitably somewhat akward use of std::visit) but establishes reasoning about the error behaviour

  3. Allows for HttpSuccess to be non-default constructible which might be relevant in cases where a complex server response is deserialized before passing it on to the client.


The downsides that I see are mainly:




  1. More complex code on the library consumer side

  2. Overhead in the non-error case due to variant wrapper




However, all-in-all the third approach feels quite unidiomatic. Are there any opinions by the experts on whether any of the approaches is superior to the others?










share|improve this question









New contributor




user823255 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I'm currently in the process of rewritting a http-client class. When it comes to the error-handling I see the three options:




  1. Throwing an exception

  2. Passing an error-type by reference

  3. Returning a std::variant<SuccessType, ErrorType>


Given the following success / error types



struct HttpSuccess {
int status;
std::string body;
};
struct HttpError {
std::string error_description;
};


The function signatures for each of the three cases would look roughly like the following





  1. HttpSuccess get(const std::string& uri); (HttpErrror would inerhit from an exception type in this case)


  2. HttpSuccess get(const std::string& uri, HttpError& error) (also std::optional<HttpError>& error possible)

  3. std::variant<HttpSuccess, HttpError> get(const std::string& uri)


Here is my reasoning why I dislike option 1 + 2:




  1. Since errors are to be expected (timeouts, internet hiccups etc), I don't want to use 1. The errors the client is dealing with are no execptions semantically.

  2. There is for me no way to ensure that the error-type is properly queried (afaik google uses rules to ensure this behaviour). So users might skip the error and proceed with the garabge return type.


This reasoning alone leaves me with option 3. The upsides that I see are the following:




  1. I can introduce different error categories easily (failure to contact the a server might be represented by a different error type than a server response error e.g.)

  2. Enforces error checking (with an admitably somewhat akward use of std::visit) but establishes reasoning about the error behaviour

  3. Allows for HttpSuccess to be non-default constructible which might be relevant in cases where a complex server response is deserialized before passing it on to the client.


The downsides that I see are mainly:




  1. More complex code on the library consumer side

  2. Overhead in the non-error case due to variant wrapper




However, all-in-all the third approach feels quite unidiomatic. Are there any opinions by the experts on whether any of the approaches is superior to the others?







c++ error-handling c++17






share|improve this question









New contributor




user823255 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




user823255 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 2 days ago









Calak

1,42512




1,42512






New contributor




user823255 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 2 days ago









user823255

97




97




New contributor




user823255 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





user823255 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






user823255 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




put on hold as off-topic by Ludisposed, 200_success, Toby Speight, tinstaafl, Incomputable 2 days ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Ludisposed, 200_success, Toby Speight, tinstaafl, Incomputable

If this question can be reworded to fit the rules in the help center, please edit the question.




put on hold as off-topic by Ludisposed, 200_success, Toby Speight, tinstaafl, Incomputable 2 days ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Ludisposed, 200_success, Toby Speight, tinstaafl, Incomputable

If this question can be reworded to fit the rules in the help center, please edit the question.








  • 1




    I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. The example code that you have posted is not reviewable in this form because it leaves us guessing at your intentions. Unlike Stack Overflow, Code Review needs to look at concrete code in a real context. Please see Why is hypothetical example code off-topic for CR?
    – Calak
    2 days ago














  • 1




    I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. The example code that you have posted is not reviewable in this form because it leaves us guessing at your intentions. Unlike Stack Overflow, Code Review needs to look at concrete code in a real context. Please see Why is hypothetical example code off-topic for CR?
    – Calak
    2 days ago








1




1




I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. The example code that you have posted is not reviewable in this form because it leaves us guessing at your intentions. Unlike Stack Overflow, Code Review needs to look at concrete code in a real context. Please see Why is hypothetical example code off-topic for CR?
– Calak
2 days ago




I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. The example code that you have posted is not reviewable in this form because it leaves us guessing at your intentions. Unlike Stack Overflow, Code Review needs to look at concrete code in a real context. Please see Why is hypothetical example code off-topic for CR?
– Calak
2 days ago















active

oldest

votes






















active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes

Popular posts from this blog

Список кардиналов, возведённых папой римским Каликстом III

Deduzione

Mysql.sock missing - “Can't connect to local MySQL server through socket”