-
-
Notifications
You must be signed in to change notification settings - Fork 219
[WIP] Feature improve exception message details (closes #184) #667
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
[WIP] Feature improve exception message details (closes #184) #667
Conversation
Codecov Report
@@ Coverage Diff @@
## master #667 +/- ##
==========================================
- Coverage 92.91% 89.83% -3.09%
==========================================
Files 65 65
Lines 3303 3511 +208
==========================================
+ Hits 3069 3154 +85
- Misses 234 357 +123
Continue to review full report at Codecov.
|
@@ -53,7 +53,7 @@ namespace Rcpp{ | |||
} else { | |||
if( ref.isNULL( ) ) throw index_out_of_bounds() ; | |||
|
|||
if( static_cast<R_xlen_t>(index) > ::Rf_xlength(ref.get__()) ) throw index_out_of_bounds() ; | |||
if( static_cast<R_xlen_t>(index) > ::Rf_xlength(ref.get__()) ) throw index_out_of_bounds("index is out of bounds. Requested %i with %i available", static_cast<R_xlen_t>(index), ::Rf_xlength(ref.get__()) ) ; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor, but to avoid overly long lines like this I often use an idiom like (pseudo-ish code):
if (condition) {
const char* fmt =
"Index out of bounds: [index=%s; extent=%s]"
throw index_out_of_bounds(fmt, index, length);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And once can wrap the "...."
over two lines as "abc" \n "def"
.
Luckily we have no strict 80 column policy here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aye, that makes it a lot more manageable. I'll switch everything over.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed through a commit that addressed this feedback.
inst/include/Rcpp/exceptions.h
Outdated
@@ -89,6 +89,48 @@ namespace Rcpp { | |||
file_io_error("file already exists", file) {} // #nocov end | |||
}; | |||
|
|||
#define RCPP_ADVANCED_EXCEPTION_CLASS(__CLASS__, __WHAT__) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor suggestion, but it'd be nice if we had a C++11 version (using variadic templates) and a C++98 version (using your current code-bloat version). We could do something like:
#if __cplusplus >= 201103L
# include <Rcpp/exceptions/cpp11/exceptions.h>
#else
# include <Rcpp/exceptions/cpp98/exceptions.h>
#endif
Let me know if you think it's worth the effort.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be very nice to have Vardiac template support... Mmm.
Would something along the lines of:
#define RCPP_CPP11_EXCEPTION_CLASS(__CLASS__, __WHAT__)
class __CLASS__ : public std::exception{ \
public: \
__CLASS__( const std::string& message ) throw() : message( __WHAT__ ){} ; \
template <typename... Args> \
__CLASS__( const char* fmt, Args&&... args ) throw() : \
message( tfm::format(fmt, std::forward<Args>(args)...) ){} ; \
virtual ~__CLASS__() throw(){} ; \
virtual const char* what() const throw() { return message.c_str() ; } \
private: \
std::string message ; \
} ;
Be acceptable?
Note: The defines in /inst/include/Rcpp/utils/tinyformat.h
will also need to receive the if __cplusplus >= 201103L
check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, something exactly like that is what I was thinking of :)
Indeed, I think we somewhat bluntly said "make tinyformat work in C++98 mode" a while back without consideration for C++11 mode, so it would make sense to guard the define there according to whether we're using C++98 or >C++98.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have some years-old tests for macros for C++11 which can probably do with brush-up. Now that we will have a decent compiler "most of the time" we may as well use it.
But we can of course not loose sight of the poor souls clinging to their old RHEL/CentOS/... systems from the last ice age. It's is probably worth our while to ensure those build too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enabling C++11 mode for tinyformat
triggered a lot of error spam that is stuttering shell. So, I've left out this change until I can investigate the file a bit more after I grab some sleep.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we may have tried that too in the past and retreated. Foggy memory on this though...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to push an updated version of the tinyformat.h
. It last received love in Aug 29, 2015. I need a fix released in March 2016 to quiet a [-Wuninitialized]
complaint. After that, everything else should work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
But let's open an issue ticket, preferably with a link to the tinyformat repo and changelog, and take this out of this somewhat growing discussion.
this example still triggers messages from R-devel CMD check after discussion with jmc, concluded that these may stem from the R side
Added support for throwing exceptions without call stacks.
commit 43e53b0 Merge: 886f5df a15ba45 Author: Dirk Eddelbuettel <edd@debian.org> Date: Tue Apr 11 13:20:10 2017 -0500 Merge pull request #663 from jimhester/exceptions_without_callstacks Added support for throwing exceptions without call stacks. commit a15ba45 Author: Jim Hester <james.f.hester@gmail.com> Date: Mon Apr 3 16:11:24 2017 -0400 Added support for throwing exceptions without call stacks.
Feature/update modules example
…ges' into feature/improved-exception-messages
Overview
This is a work in progress (WIP) PR to upgrade the exception messages found in Rcpp.
For details on the contents of the PR, please see #184. (The issue ticket contains GitHub search URL for each Rcpp exception message.)
Changes:
RCPP_ADVANCED_EXCEPTION_CLASS
macro that mimics the structure of theRcpp::stop()
/Rcpp::warning()
implementations.no_such_field
not_compatible
tonot_a_matrix
ininst\include\Rcpp\vector\Matrix.h
(FYI, athrow
was missing on one of the statements).Presently, I've held off on removing
reference_creation_error
as it is not used but it is referenced within the documentation.Misc
This branch will likely need to be rebased after @jimhester's #663 PR.