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

Use Rcpp::stop instead of throw (closes #401) #402

Merged
merged 2 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
8 changes: 8 additions & 0 deletions inst/NEWS.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
\newcommand{\ghpr}{\href{https://github.com/Rblp/Rblpapi/pull/#1}{##1}}
\newcommand{\ghit}{\href{https://github.com/Rblp/Rblpapi/issues/#1}{##1}}

\section{Changes in Rblpapi version 0.3.16 (2025-xx-yy)}{
\itemize{
\item A quoto error message is now improved (Rodolphe Duge in \ghpr{400})
\item Convert remaining \code{throw} into \code{Rcpp::stop} (Dirk in
\ghpr{402} fixing \ghit{401})
}
}

\section{Changes in Rblpapi version 0.3.15 (2024-09-18)}{
\itemize{
\item A warning is now issued if more than 1000 results are returned
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
Loading