Skip to content

Commit

Permalink
Use Rcpp::stop instead of throw (closes #401)
Browse files Browse the repository at this point in the history
  • Loading branch information
eddelbuettel committed Dec 5, 2024
1 parent 1f43d9a commit e376641
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 44 deletions.
11 changes: 11 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
2024-12-05 Dirk Eddelbuettel <[email protected]>

* src/bdh.cpp: Use Rcpp::stop instead of throw
* src/bdp.cpp: Idem
* src/bds.cpp: Idem
* src/beqs.cpp: Idem
* src/blpapi_utils.cpp: Idem
* src/bsrch.cpp: Idem
* src/lookup.cpp: Idem
* src/subscribe.cpp: Idem

2024-12-04 Dirk Eddelbuettel <[email protected]>

* DESCRIPTION (Version, Date): Roll micro version and date
Expand Down
10 changes: 5 additions & 5 deletions src/bdh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ using BloombergLP::blpapi::Name;
std::string getSecurityName(Event& event) {
MessageIterator msgIter(event);
if (!msgIter.next()) {
throw std::logic_error("Not a valid MessageIterator.");
Rcpp::stop("Not a valid MessageIterator.");
}

Message msg = msgIter.message();
Element response = msg.asElement();
if(std::strcmp(response.name().string(),"HistoricalDataResponse")) {
throw std::logic_error("Not a valid HistoricalDataResponse.");
Rcpp::stop("Not a valid HistoricalDataResponse.");
}

Element securityData = response.getElement(Name{"securityData"});
Expand All @@ -61,14 +61,14 @@ Rcpp::List HistoricalDataResponseToDF(Event& event, const std::vector<std::strin
const std::vector<RblpapiT>& rtypes, bool verbose=FALSE) {
MessageIterator msgIter(event);
if (!msgIter.next()) {
throw std::logic_error("Not a valid MessageIterator.");
Rcpp::stop("Not a valid MessageIterator.");
}

Message msg = msgIter.message();
Element response = msg.asElement();
if (verbose) response.print(Rcpp::Rcout);
if (std::strcmp(response.name().string(),"HistoricalDataResponse")) {
throw std::logic_error("Not a valid HistoricalDataResponse.");
Rcpp::stop("Not a valid HistoricalDataResponse.");
}
Element securityData = response.getElement(Name{"securityData"});
Element fieldData = securityData.getElement(Name{"fieldData"});
Expand All @@ -81,7 +81,7 @@ Rcpp::List HistoricalDataResponseToDF(Event& event, const std::vector<std::strin
for(size_t j = 0; j < row.numElements(); ++j) {
Element e = row.getElement(j);
auto it = std::find(fields.begin(),fields.end(),e.name().string());
if(it==fields.end()) { throw std::logic_error("Unexpected field returned."); }
if(it==fields.end()) { Rcpp::stop("Unexpected field returned."); }
int colindex = std::distance(fields.begin(),it);
populateDfRow(res[colindex], i, e, rtypes[colindex]);
}
Expand Down
14 changes: 7 additions & 7 deletions src/bdp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ using BloombergLP::blpapi::Name;
void getBDPResult(Event& event, Rcpp::List& res, const std::vector<std::string>& securities, const std::vector<std::string>& colnames, const std::vector<RblpapiT>& rtypes, bool verbose) {
MessageIterator msgIter(event);
if (!msgIter.next()) {
throw std::logic_error("Not a valid MessageIterator.");
Rcpp::stop("Not a valid MessageIterator.");
}
Message msg = msgIter.message();
Element response = msg.asElement();
if (verbose) response.print(Rcpp::Rcout);
if (std::strcmp(response.name().string(),"ReferenceDataResponse")) {
throw std::logic_error("Not a valid ReferenceDataResponse.");
Rcpp::stop("Not a valid ReferenceDataResponse.");
}

const Name responseError("responseError");
Expand All @@ -65,7 +65,7 @@ void getBDPResult(Event& event, Rcpp::List& res, const std::vector<std::string>&
errMsg = errorElement.getElementAsString(messageTag);
}
Rcpp::Rcerr << "REQUEST FAILED: " << errorElement << std::endl;
throw std::logic_error("bdp result: a responseError was received with message: (" + errMsg + ")");
Rcpp::stop("bdp result: a responseError was received with message: (" + errMsg + ")");
}

Element securityData = response.getElement(Name{"securityData"});
Expand All @@ -76,14 +76,14 @@ void getBDPResult(Event& event, Rcpp::List& res, const std::vector<std::string>&

// check that the seqNum matches the order of the securities vector (it's a grave error to screw this up)
if(securities[row_index].compare(this_security.getElementAsString(Name{"security"}))!=0) {
throw std::logic_error("mismatched Security sequence, please report a bug.");
Rcpp::stop("mismatched Security sequence, please report a bug.");
}
Element fieldData = this_security.getElement(Name{"fieldData"});
for(size_t j = 0; j < fieldData.numElements(); ++j) {
Element e = fieldData.getElement(j);
auto col_iter = std::find(colnames.begin(), colnames.end(), e.name().string());
if (col_iter == colnames.end()) {
throw std::logic_error(std::string("column is not expected: ") + e.name().string());
Rcpp::stop(std::string("column is not expected: ") + e.name().string());
}
size_t col_index = std::distance(colnames.begin(),col_iter);
populateDfRow(res[col_index],row_index,e,rtypes[col_index]);
Expand All @@ -98,7 +98,7 @@ Rcpp::List bdp_Impl(SEXP con_, std::vector<std::string> securities, std::vector<
SEXP options_, SEXP overrides_, bool verbose, SEXP identity_) {

// via Rcpp Attributes we get a try/catch block with error propagation to R "for free"
Session* session =
Session* session =
reinterpret_cast<Session*>(checkExternalPointer(con_, "blpapi::Session*"));

// get the field info
Expand All @@ -114,7 +114,7 @@ Rcpp::List bdp_Impl(SEXP con_, std::vector<std::string> securities, std::vector<
if (!session->openService(rdsrv.c_str())) {
Rcpp::stop("Failed to open " + rdsrv);
}

Service refDataService = session->getService(rdsrv.c_str());
Request request = refDataService.createRequest("ReferenceDataRequest");
createStandardRequest(request, securities, fields, options_, overrides_);
Expand Down
6 changes: 3 additions & 3 deletions src/bds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void populateDfRowBDS(Rcpp::RObject ans, R_len_t row_index, Element& e) {
case BLPAPI_DATATYPE_CORRELATION_ID:
INTEGER(ans)[row_index] = e.getValueAsInt32(); break;
default:
throw std::logic_error("Unsupported datatype outside of api blpapi_DataType_t scope.");
Rcpp::stop("Unsupported datatype outside of api blpapi_DataType_t scope.");
}
}

Expand Down Expand Up @@ -218,14 +218,14 @@ Rcpp::List bulkArrayToDf(Element& fieldData) {
Rcpp::List BulkDataResponseToDF(Event& event, std::string& requested_field, std::string response_type, bool verbose) {
MessageIterator msgIter(event);
if(!msgIter.next()) {
throw std::logic_error("Not a valid MessageIterator.");
Rcpp::stop("Not a valid MessageIterator.");
}

Message msg = msgIter.message();
Element response = msg.asElement();
if (verbose) response.print(Rcpp::Rcout);
if(std::strcmp(response.name().string(),response_type.c_str())) {
throw std::logic_error("Not a valid " + response_type + ".");
Rcpp::stop("Not a valid " + response_type + ".");
}
Element securityData = response.getElement(Name{"securityData"});

Expand Down
4 changes: 2 additions & 2 deletions src/beqs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ using BloombergLP::blpapi::Name;
Rcpp::DataFrame processResponseEvent(Event event, const bool verbose) {

MessageIterator msgIter(event); // create message iterator
if (!msgIter.next()) throw std::logic_error("Not a valid MessageIterator.");
if (!msgIter.next()) Rcpp::stop("Not a valid MessageIterator.");

Message msg = msgIter.message(); // get message
if (verbose) msg.print(Rcpp::Rcout);

Element response = msg.asElement(); // view as element
if (std::strcmp(response.name().string(), "BeqsResponse") != 0)
throw std::logic_error("Not a valid EQSDataResponse.");
Rcpp::stop("Not a valid EQSDataResponse.");

Element data = msg.getElement(Name{"data"}); // get data payload, extract field with display units
Element fieldDisplayUnits = data.getElement(Name{"fieldDisplayUnits"});
Expand Down
44 changes: 22 additions & 22 deletions src/blpapi_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,31 +50,31 @@ using BloombergLP::blpapi::Name;

void* checkExternalPointer(SEXP xp_, const char* valid_tag) {
if(xp_ == R_NilValue) {
throw std::logic_error("External pointer is NULL.");
Rcpp::stop("External pointer is NULL.");
}
if(TYPEOF(xp_) != EXTPTRSXP) {
throw std::logic_error("Not an external pointer.");
Rcpp::stop("Not an external pointer.");
}

if(R_ExternalPtrTag(xp_)==R_NilValue) {
throw std::logic_error("External pointer tag is NULL.");
Rcpp::stop("External pointer tag is NULL.");
}
const char* xp_tag = CHAR(PRINTNAME(R_ExternalPtrTag(xp_)));
if(!xp_tag) {
throw std::logic_error("External pointer tag is blank.");
Rcpp::stop("External pointer tag is blank.");
}
if(std::strcmp(xp_tag,valid_tag) != 0) {
throw std::logic_error("External pointer tag does not match.");
Rcpp::stop("External pointer tag does not match.");
}
if(R_ExternalPtrAddr(xp_)==NULL) {
throw std::logic_error("External pointer address is null.");
Rcpp::stop("External pointer address is null.");
}
return R_ExternalPtrAddr(xp_);
}

const int bbgDateToRDate(const Datetime& bbg_date) {
if(bbg_date.hasParts(DatetimeParts::TIME)) {
throw std::logic_error("Attempt to convert a Datetime with time parts set to an R Date.");
Rcpp::stop("Attempt to convert a Datetime with time parts set to an R Date.");
}
const boost::gregorian::date r_epoch(1970,1,1);
boost::gregorian::date bbg_boost_date(bbg_date.year(),bbg_date.month(),bbg_date.day());
Expand All @@ -84,10 +84,10 @@ const int bbgDateToRDate(const Datetime& bbg_date) {

const int bbgDateToRDate(const double yyyymmdd_date) {
if(yyyymmdd_date < 0) {
throw std::logic_error("Attempt to convert a negative double value to an R Date.");
Rcpp::stop("Attempt to convert a negative double value to an R Date.");
}
if(trunc(yyyymmdd_date)!=yyyymmdd_date) {
throw std::logic_error("Attempt to convert a double value with time parts set to an R Date.");
Rcpp::stop("Attempt to convert a double value with time parts set to an R Date.");
}

const boost::gregorian::date r_epoch(1970,1,1);
Expand Down Expand Up @@ -149,17 +149,17 @@ void appendOptionsToRequest(Request& request, SEXP options_) {
Rcpp::CharacterVector options(options_);

if(!options.hasAttribute("names")) {
throw std::logic_error("Request options must be named.");
Rcpp::stop("Request options must be named.");
}

if(options.attr("names") == R_NilValue) {
throw std::logic_error("Request optionnames must not be null.");
Rcpp::stop("Request optionnames must not be null.");
}

Rcpp::CharacterVector options_names(options.attr("names"));

if(options.length() && options_names.length()==0) {
throw std::logic_error("Request options must be non empty and named.");
Rcpp::stop("Request options must be non empty and named.");
}

for(R_len_t i = 0; i < options.length(); i++) {
Expand All @@ -172,13 +172,13 @@ void appendOverridesToRequest(Request& request, SEXP overrides_) {
Rcpp::CharacterVector overrides(overrides_);

if(!overrides.hasAttribute("names") || overrides.attr("names") == R_NilValue) {
throw std::logic_error("Request overrides must be named.");
Rcpp::stop("Request overrides must be named.");
}

Rcpp::CharacterVector overrides_names(overrides.attr("names"));

if(overrides.length() && overrides_names.length()==0) {
throw std::logic_error("Request overrides must be non empty and named.");
Rcpp::stop("Request overrides must be non empty and named.");
}

Element request_overrides = request.getElement(Name{"overrides"});
Expand Down Expand Up @@ -367,25 +367,25 @@ FieldInfo getFieldType(Session *session, Service& fieldInfoService, const std::s
//msg.asElement().print(std::cout);
Element fields = msg.getElement(Name{"fieldData"});
if(fields.numValues() > 1) {
throw std::logic_error("getFieldType: too many fields returned.");
Rcpp::stop("getFieldType: too many fields returned.");
}
Element field = fields.getValueAsElement(0);
if (!field.hasElement(Name{"id"})) {
throw std::logic_error("Did not find 'id' in repsonse.");
Rcpp::stop("Did not find 'id' in repsonse.");
}
if (field.hasElement(Name{"fieldError"})) {
std::ostringstream err;
err << "Bad field: " << field.getElementAsString(Name{"id"}) << std::endl;
throw std::logic_error(err.str());
Rcpp::stop(err.str());
}
if (!field.hasElement(Name{"fieldInfo"})) {
throw std::logic_error("Did not find fieldInfo in repsonse.");
Rcpp::stop("Did not find fieldInfo in repsonse.");
}
Element fieldInfo = field.getElement(Name{"fieldInfo"});
if (!fieldInfo.hasElement(Name{"mnemonic"}) ||
!fieldInfo.hasElement(Name{"datatype"}) ||
!fieldInfo.hasElement(Name{"ftype"})) {
throw std::logic_error("fieldInfo missing info mnemonic/datatype/ftype.");
Rcpp::stop("fieldInfo missing info mnemonic/datatype/ftype.");
}
ans.id = field.getElementAsString(Name{"id"});
ans.mnemonic = fieldInfo.getElementAsString(Name{"mnemonic"});
Expand All @@ -404,7 +404,7 @@ std::vector<FieldInfo> getFieldTypes(Session *session,
const std::vector<std::string> &fields) {
const std::string APIFLDS_SVC("//blp/apiflds");
if (!session->openService(APIFLDS_SVC.c_str())) {
throw std::logic_error(std::string("Failed to open " + APIFLDS_SVC));
Rcpp::stop(std::string("Failed to open " + APIFLDS_SVC));
}
Service fieldInfoService = session->getService(APIFLDS_SVC.c_str());
std::vector<FieldInfo> ans;
Expand All @@ -417,7 +417,7 @@ std::vector<FieldInfo> getFieldTypes(Session *session,
Rcpp::List allocateDataFrame(const vector<string>& rownames, const vector<string>& colnames, vector<RblpapiT>& coltypes) {

if(colnames.size() != coltypes.size()) {
throw std::logic_error("colnames size inconsistent with column types size.");
Rcpp::stop("colnames size inconsistent with column types size.");
}

Rcpp::List ans(colnames.size());
Expand All @@ -433,7 +433,7 @@ Rcpp::List allocateDataFrame(const vector<string>& rownames, const vector<string
Rcpp::List allocateDataFrame(size_t nrows, const vector<string>& colnames, const vector<RblpapiT>& coltypes) {

if(colnames.size() != coltypes.size()) {
throw std::logic_error("colnames size inconsistent with column types size.");
Rcpp::stop("colnames size inconsistent with column types size.");
}

Rcpp::List ans(colnames.size());
Expand Down
4 changes: 2 additions & 2 deletions src/bsrch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ using BloombergLP::blpapi::Name;
Rcpp::DataFrame processBsrchResponse(Event event, const bool verbose) {

MessageIterator msgIter(event); // create message iterator
if (!msgIter.next()) throw std::logic_error("Not a valid MessageIterator.");
if (!msgIter.next()) Rcpp::stop("Not a valid MessageIterator.");

Message msg = msgIter.message(); // get message
if (verbose) msg.print(Rcpp::Rcout);

Element response = msg.asElement(); // view as element
if (std::strncmp(response.name().string(), "GridResponse", std::strlen("GridResponse")) != 0)
throw std::logic_error("Not a valid GridResponse.");
Rcpp::stop("Not a valid GridResponse.");

// exrsvc provides a grid in the form of DataRecords
// Extract the dimensions and key attributes before processing
Expand Down
2 changes: 1 addition & 1 deletion src/lookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void processMessage(bbg::Message &msg, InstrumentListResults &matches, const boo
bbg::Element response = msg.asElement();
if (verbose) response.print(Rcpp::Rcout);
if (std::strcmp(response.name().string(),"InstrumentListResponse")) {
throw std::logic_error("Not a valid InstrumentListResponse.");
Rcpp::stop("Not a valid InstrumentListResponse.");
}

bbg::Element data = response.getElement(bbg::Name{"results"});
Expand Down
4 changes: 2 additions & 2 deletions src/subscribe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ SEXP subscribe_Impl(SEXP con_, std::vector<std::string> securities, std::vector<
SEXP options_, SEXP identity_) {

// via Rcpp Attributes we get a try/catch block with error propagation to R "for free"
Session* session =
Session* session =
reinterpret_cast<Session*>(checkExternalPointer(con_, "blpapi::Session*"));

const std::string mdsrv = "//blp/mktdata";
Expand Down Expand Up @@ -214,7 +214,7 @@ SEXP subscribe_Impl(SEXP con_, std::vector<std::string> securities, std::vector<
Rcpp::List ans;
auto it = BlpapiEventToString.find(event.eventType());
if(it==BlpapiEventToString.end()) {
throw Rcpp::exception("Unknown event type.");
Rcpp::stop("Unknown event type.");
}
ans["event.type"] = it->second;
size_t cid(msg.correlationId().asInteger());
Expand Down

0 comments on commit e376641

Please sign in to comment.