aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2017-11-08 16:03:10 -0800
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:05:05 -0800
commit7efdd96a452c1cc40862691adedc6f19bc51d358 (patch)
treee8177398ce624030615eae6d2fbe325eb8c51e86 /host/lib
parentfdfe1f4c3cc7c11696e425fc9c13f029c77f79fc (diff)
downloaduhd-7efdd96a452c1cc40862691adedc6f19bc51d358.tar.gz
uhd-7efdd96a452c1cc40862691adedc6f19bc51d358.tar.bz2
uhd-7efdd96a452c1cc40862691adedc6f19bc51d358.zip
rpc: Add feature to retrieve an error string
It can be helpful to go back to the RPC server for clarification on what just happened. This adds an optional argument to the RPC client for how to retrieve that info.
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/utils/rpc.hpp64
1 files changed, 58 insertions, 6 deletions
diff --git a/host/lib/utils/rpc.hpp b/host/lib/utils/rpc.hpp
index ac619ef58..9d2645130 100644
--- a/host/lib/utils/rpc.hpp
+++ b/host/lib/utils/rpc.hpp
@@ -20,6 +20,7 @@
#include <rpc/client.h>
#include <rpc/rpc_error.h>
+#include <uhd/utils/log.hpp>
#include <uhd/exception.hpp>
#include <boost/format.hpp>
@@ -36,15 +37,31 @@ class rpc_client
public:
using sptr = std::shared_ptr<rpc_client>;
- static sptr make(std::string const& addr, uint16_t port) {
- return std::make_shared<rpc_client>(addr, port);
+ static sptr make(
+ const std::string &addr,
+ const uint16_t port,
+ const std::string &get_last_error_cmd=""
+ ) {
+ return std::make_shared<rpc_client>(addr, port, get_last_error_cmd);
}
/*!
* \param addr An IP address to connect to
* \param port Port to connect to
+ * \param get_last_error_cmd A command that queries an error string from
+ * the RPC server. If set, the RPC client will
+ * try and use this command to fetch information
+ * about what went wrong on the client side.
*/
- rpc_client(std::string const& addr, uint16_t port) : _client(addr, port) {}
+ rpc_client(
+ const std::string &addr,
+ const uint16_t port,
+ std::string const &get_last_error_cmd=""
+ ) : _client(addr, port)
+ , _get_last_error_cmd(get_last_error_cmd)
+ {
+ // nop
+ }
/*! Perform an RPC request.
*
@@ -64,9 +81,13 @@ class rpc_client
return _client.call(func_name, std::forward<Args>(args)...)
.template as<return_type>();
} catch (const ::rpc::rpc_error &ex) {
+ const std::string error = _get_last_error_safe();
+ if (not error.empty()) {
+ UHD_LOG_ERROR("RPC", error);
+ }
throw uhd::runtime_error(str(
boost::format("Error during RPC call to `%s'. Error message: %s")
- % func_name % ex.what()
+ % func_name % (error.empty() ? ex.what() : error)
));
} catch (const std::bad_cast& ex) {
throw uhd::runtime_error(str(
@@ -93,9 +114,13 @@ class rpc_client
try {
_client.call(func_name, std::forward<Args>(args)...);
} catch (const ::rpc::rpc_error &ex) {
+ const std::string error = _get_last_error_safe();
+ if (not error.empty()) {
+ UHD_LOG_ERROR("RPC", error);
+ }
throw uhd::runtime_error(str(
boost::format("Error during RPC call to `%s'. Error message: %s")
- % func_name % ex.what()
+ % func_name % (error.empty() ? ex.what() : error)
));
} catch (const std::bad_cast& ex) {
throw uhd::runtime_error(str(
@@ -140,9 +165,36 @@ class rpc_client
}
private:
+ /*! Pull the last error out of the RPC server. Not thread-safe, meant to
+ * be called from notify() or request().
+ *
+ * This function will do its best not to get in anyone's way. If it can't
+ * get an error string, it'll return an empty string.
+ */
+ std::string _get_last_error_safe()
+ {
+ if (_get_last_error_cmd.empty()) {
+ return "";
+ }
+ try {
+ return _client.call(_get_last_error_cmd).as<std::string>();
+ } catch (const ::rpc::rpc_error &ex) {
+ // nop
+ } catch (const std::bad_cast& ex) {
+ // nop
+ } catch (...) {
+ // nop
+ }
+ return "";
+ }
+
+ //! Reference the actual RPC client
+ ::rpc::client _client;
+ //! If set, this is the command that will retrieve an error
+ const std::string _get_last_error_cmd;
+
std::string _token;
std::mutex _mutex;
- ::rpc::client _client;
};
} /* namespace uhd */