Skip to content

Commit 8f2a101

Browse files
authored
Merge pull request #677 from coatless/feature/improved-exception-msgs
Improved exception messages (close #184)
2 parents 25c2369 + dd926e4 commit 8f2a101

File tree

19 files changed

+249
-74
lines changed

19 files changed

+249
-74
lines changed

ChangeLog

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
2017-04-20 James J Balamuta <[email protected]>
2+
3+
* inst/include/Rcpp/api/meat/DottedPairImpl.h: Corrected format specifier
4+
from '%s' to '%i'.
5+
6+
7+
2017-04-18 James J Balamuta <[email protected]>
8+
9+
* inst/include/Rcpp/vector/Matrix.h: Corrected exception throws from
10+
not_compatible to not_a_matrix.
11+
* inst/include/Rcpp/S4.h: Fixed documentation detailing exception class
12+
throw.
13+
* inst/include/Rcpp/Environment.h: Improved error handling messages
14+
* inst/include/Rcpp/Function.h: idem
15+
* inst/include/Rcpp/Promise.h: idem
16+
* inst/include/Rcpp/String.h: idem
17+
* inst/include/Rcpp/Symbol.h: idem
18+
* inst/include/Rcpp/XPtr.h: idem
19+
* inst/include/Rcpp/as.h: idem
20+
* inst/include/Rcpp/r_cast.h: idem
21+
* inst/include/Rcpp/api/meat/DottedPairImpl.h: idem
22+
* inst/include/Rcpp/internal/export.h: idem
23+
* inst/include/Rcpp/proxy/DottedPairProxy.h: idem
24+
* inst/include/Rcpp/proxy/SlotProxy.h: idem
25+
* inst/include/Rcpp/vector/MatrixColumn.h: idem
26+
* inst/include/Rcpp/vector/MatrixRow.h: idem
27+
* inst/include/Rcpp/vector/Vector.h: idem
28+
129
2017-04-17 James J Balamuta <[email protected]>
230

331
* inst/include/Rcpp/Rcpp/exceptions/cpp11/exceptions.h: Removed

inst/NEWS.Rd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
variadic templating for \code{Rcpp::stop} and \code{Rcpp::warning}
1818
(James Balamuta in \ghpr{676}).
1919
\item Exception messages have been rewritten to provide additional
20-
information. (James Balamuta in \ghpr{676}, ?? addressing \ghit{184}).
20+
information. (James Balamuta in \ghpr{676} and \ghpr{677} addressing \ghit{184}).
2121
}
2222
\item Changes in Rcpp Documentation:
2323
\itemize{

inst/include/Rcpp/Environment.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ namespace Rcpp{
3939
try {
4040
Shield<SEXP> res( Rcpp_eval( Rf_lang2( asEnvironmentSym, x ) ) );
4141
return res ;
42-
} catch( const eval_error& ex){
43-
throw not_compatible( "cannot convert to environment" ) ;
42+
} catch( const eval_error& ex) {
43+
const char* fmt = "Cannot convert object to an environment: "
44+
"[type=%s; target=ENVSXP].";
45+
throw not_compatible(fmt, Rf_type2char(TYPEOF(x)));
4446
}
4547
}
4648

@@ -115,7 +117,7 @@ namespace Rcpp{
115117
}
116118
return res ;
117119
}
118-
120+
119121
/**
120122
* Get an object from the environment
121123
*
@@ -126,16 +128,16 @@ namespace Rcpp{
126128
SEXP get(Symbol name) const {
127129
SEXP env = Storage::get__() ;
128130
SEXP res = Rf_findVarInFrame( env, name ) ;
129-
131+
130132
if( res == R_UnboundValue ) return R_NilValue ;
131-
133+
132134
/* We need to evaluate if it is a promise */
133135
if( TYPEOF(res) == PROMSXP){
134136
res = Rf_eval( res, env ) ;
135137
}
136138
return res ;
137139
}
138-
140+
139141

140142
/**
141143
* Get an object from the environment or one of its
@@ -157,7 +159,7 @@ namespace Rcpp{
157159
}
158160
return res ;
159161
}
160-
162+
161163
/**
162164
* Get an object from the environment or one of its
163165
* parents
@@ -167,13 +169,13 @@ namespace Rcpp{
167169
SEXP find(Symbol name) const{
168170
SEXP env = Storage::get__() ;
169171
SEXP res = Rf_findVar( name, env ) ;
170-
172+
171173
if( res == R_UnboundValue ) {
172174
// Pass on the const char* to the RCPP_EXCEPTION_CLASS's
173175
// const std::string& requirement
174176
throw binding_not_found(name.c_str()) ;
175177
}
176-
178+
177179
/* We need to evaluate if it is a promise */
178180
if( TYPEOF(res) == PROMSXP){
179181
res = Rf_eval( res, env ) ;

inst/include/Rcpp/Function.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ namespace Rcpp{
4444
Storage::set__(x);
4545
break;
4646
default:
47-
throw not_compatible("cannot convert to function") ;
47+
const char* fmt = "Cannot convert object to a function: "
48+
"[type=%s; target=CLOSXP, SPECIALSXP, or "
49+
"BUILTINSXP].";
50+
throw not_compatible(fmt, Rf_type2char(TYPEOF(x)));
4851
}
4952
}
5053

@@ -87,7 +90,7 @@ namespace Rcpp{
8790
SEXP environment() const {
8891
SEXP fun = Storage::get__() ;
8992
if( TYPEOF(fun) != CLOSXP ) {
90-
throw not_a_closure() ;
93+
throw not_a_closure(Rf_type2char(TYPEOF(fun)));
9194
}
9295
return CLOENV(fun) ;
9396
}

inst/include/Rcpp/Promise.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ namespace Rcpp{
2929
RCPP_GENERATE_CTOR_ASSIGN(Promise_Impl)
3030

3131
Promise_Impl( SEXP x){
32-
if( TYPEOF(x) != PROMSXP)
33-
throw not_compatible("not a promise") ;
32+
if( TYPEOF(x) != PROMSXP) {
33+
const char* fmt = "Not a promise: [type = %s].";
34+
throw not_compatible(fmt, Rf_type2char(TYPEOF(x)));
35+
}
36+
3437
Storage::set__(x) ;
3538
}
3639

inst/include/Rcpp/S4.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ namespace Rcpp{
5252
* Creates an S4 object of the requested class.
5353
*
5454
* @param klass name of the target S4 class
55-
* @throw not_s4 if klass does not map to a known S4 class
55+
* @throw S4_creation_error if klass does not map to a known S4 class
5656
*/
5757
S4_Impl( const std::string& klass ){
5858
Shield<SEXP> x( R_do_new_object(R_do_MAKE_CLASS(klass.c_str())) );
@@ -66,6 +66,9 @@ namespace Rcpp{
6666
*/
6767
bool is( const std::string& clazz) const ;
6868

69+
/**
70+
* @throw not_s4 if x is not an S4 class
71+
*/
6972
void update(SEXP x){
7073
if( ! ::Rf_isS4(x) ) throw not_s4() ;
7174
}

inst/include/Rcpp/String.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,13 @@ namespace Rcpp {
7171
data = charsxp;
7272
}
7373

74-
if (::Rf_isString(data) && ::Rf_length(data) != 1)
75-
throw ::Rcpp::not_compatible("expecting a single value");
74+
if (::Rf_isString(data) && ::Rf_length(data) != 1) {
75+
const char* fmt = "Expecting a single string value: "
76+
"[type=%s; extent=%i].";
77+
throw ::Rcpp::not_compatible(fmt,
78+
Rf_type2char(TYPEOF(data)),
79+
::Rf_length(data));
80+
}
7681

7782
valid = true;
7883
buffer_ready = false;

inst/include/Rcpp/Symbol.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ namespace Rcpp{
6262
break ;
6363
}
6464
default:
65-
throw not_compatible("cannot convert to symbol (SYMSXP)") ;
65+
const char* fmt = "Cannot convert object to a symbol: "
66+
"[type=%s; target=SYMSXP].";
67+
throw not_compatible(fmt, Rf_type2char(TYPEOF(x)));
6668
}
6769
}
6870

inst/include/Rcpp/XPtr.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,11 @@ class XPtr :
6464
* @param xp external pointer to wrap
6565
*/
6666
explicit XPtr(SEXP x, SEXP tag = R_NilValue, SEXP prot = R_NilValue) {
67-
if( TYPEOF(x) != EXTPTRSXP )
68-
throw ::Rcpp::not_compatible( "expecting an external pointer" ) ;
67+
if( TYPEOF(x) != EXTPTRSXP ) {
68+
const char* fmt = "Expecting an external pointer: [type=%s].";
69+
throw ::Rcpp::not_compatible(fmt, Rf_type2char(TYPEOF(x)));
70+
}
71+
6972
Storage::set__(x) ;
7073
R_SetExternalPtrTag( x, tag ) ;
7174
R_SetExternalPtrProtected( x, prot ) ;

inst/include/Rcpp/api/meat/DottedPairImpl.h

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,18 @@ namespace Rcpp{
5151
if( index == 0 ) {
5252
push_front( object ) ;
5353
} else {
54-
if( ref.isNULL( ) ) throw index_out_of_bounds() ;
54+
if( ref.isNULL( ) ) {
55+
throw index_out_of_bounds("Object being inserted into Dotted Pair is null.");
56+
}
57+
58+
if( static_cast<R_xlen_t>(index) > ::Rf_xlength(ref.get__()) ) {
59+
const char* fmt = "Dotted Pair index is out of bounds: "
60+
"[index=%i; extent=%i].";
5561

56-
if( static_cast<R_xlen_t>(index) > ::Rf_xlength(ref.get__()) ) throw index_out_of_bounds() ;
62+
throw index_out_of_bounds(fmt,
63+
static_cast<R_xlen_t>(index),
64+
::Rf_xlength(ref.get__()) ) ;
65+
}
5766

5867
size_t i=1;
5968
SEXP x = ref.get__() ;
@@ -70,7 +79,14 @@ namespace Rcpp{
7079
template <typename T>
7180
void DottedPairImpl<CLASS>::replace( const int& index, const T& object ) {
7281
CLASS& ref = static_cast<CLASS&>(*this) ;
73-
if( static_cast<R_xlen_t>(index) >= ::Rf_xlength(ref.get__()) ) throw index_out_of_bounds() ;
82+
if( static_cast<R_xlen_t>(index) >= ::Rf_xlength(ref.get__()) ) {
83+
const char* fmt = "Dotted Pair index is out of bounds: "
84+
"[index=%i; extent=%i].";
85+
86+
throw index_out_of_bounds(fmt,
87+
static_cast<R_xlen_t>(index),
88+
::Rf_xlength(ref.get__()) ) ;
89+
}
7490

7591
Shield<SEXP> x( pairlist( object ) );
7692
SEXP y = ref.get__() ;
@@ -84,7 +100,15 @@ namespace Rcpp{
84100
template <typename CLASS>
85101
void DottedPairImpl<CLASS>::remove( const size_t& index ) {
86102
CLASS& ref = static_cast<CLASS&>(*this) ;
87-
if( static_cast<R_xlen_t>(index) >= Rf_xlength(ref.get__()) ) throw index_out_of_bounds() ;
103+
if( static_cast<R_xlen_t>(index) >= Rf_xlength(ref.get__()) ) {
104+
const char* fmt = "Dotted Pair index is out of bounds: "
105+
"[index=%i; extent=%i].";
106+
107+
throw index_out_of_bounds(fmt,
108+
static_cast<R_xlen_t>(index),
109+
::Rf_xlength(ref.get__()) ) ;
110+
}
111+
88112
if( index == 0 ){
89113
ref.set__( CDR( ref.get__() ) ) ;
90114
} else{

0 commit comments

Comments
 (0)