Change async_method_call to be no-throw
The async_method_call() would throw despite the inferred promise that it
would not, because the handler would be passed an error_code object. But
that would only protect from the dbus method call itself. When it came
time to unpack the response, the read_into_tuple(...) method call would
throw if the received types did not match the expected types. And
because this throw would happen in a separate boost::asio context, the
throw would always be fatal. Now, any exception during the D-Bus call or
unpacking of parameters will result in an error_code getting passed into
the handler so it can take appropriate action.
This also updates the example to remove try/catch statements around the
async_method_call and yield_method_call examples and shows what happens
if the method calls fail because of different types of errors
(api/function does not exist vs. incorrect unpack types).
Tested-by: run asio-example to see that it works as expected:
# /tmp/asio-example
voidBar() -> 42
fooYield(yield, 41)...
async_send callback
error with async_send
ipmiInterface:execute(61)
async_method_call callback
/org/openbmc/control/bmc0
/org/openbmc/control/flash/bmc
fooYield(yield, 41)...
ipmi call returns OK!
foo(41) -> 42
async_method_call callback
async_method_call expected failure: generic:foo(41) -> 42
yielding call to foo OK! (-> 42)
22
async call to Properties.Get serialized via yield OK!
TestYieldFunction return 42
yielding call to foo OK! (-> 42)
yielding call to TestYieldFunction serialized via yield OK!
fooYield(yield, 41)...
foo(41) -> 42
async call to Properties.Get serialized via yield OK!
yielding call to foo OK! (-> 42)
TestYieldFunction expected error: generic:22
TestYieldFunctionNotExits expected error: generic:53
*** tick ***
*** tock ***
*** tick ***
*** tick ***
*** tick ***
Change-Id: I53c91484ed496556342b3ed0a58b690872a2d676
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
stuff
Change-Id: I48da27be7ba8c63f44c12a8b79fffb8f3e085648
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/example/asio-example.cpp b/example/asio-example.cpp
index 2cd1323..f04af3f 100644
--- a/example/asio-example.cpp
+++ b/example/asio-example.cpp
@@ -146,17 +146,10 @@
{
boost::system::error_code ec;
int testValue = 0;
- try
- {
- testValue = conn->yield_method_call<int>(
- yield, ec, "xyz.openbmc_project.asio-test",
- "/xyz/openbmc_project/test", "xyz.openbmc_project.test",
- "TestYieldFunction", int(41));
- }
- catch (sdbusplus::exception::SdBusError& e)
- {
- std::cout << "oops: " << e.what() << "\n";
- }
+ testValue = conn->yield_method_call<int>(
+ yield, ec, "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test",
+ "xyz.openbmc_project.test", "TestYieldFunction", int(41));
+
if (!ec && testValue == 42)
{
std::cout
@@ -166,6 +159,35 @@
{
std::cout << "ec = " << ec << ": " << testValue << "\n";
}
+
+ ec.clear();
+ auto badValue = conn->yield_method_call<std::string>(
+ yield, ec, "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test",
+ "xyz.openbmc_project.test", "TestYieldFunction", int(41));
+
+ if (!ec)
+ {
+ std::cout
+ << "yielding call to TestYieldFunction returned the wrong type\n";
+ }
+ else
+ {
+ std::cout << "TestYieldFunction expected error: " << ec << "\n";
+ }
+
+ ec.clear();
+ auto unUsedValue = conn->yield_method_call<std::string>(
+ yield, ec, "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test",
+ "xyz.openbmc_project.test", "TestYieldFunctionNotExits", int(41));
+
+ if (!ec)
+ {
+ std::cout << "TestYieldFunctionNotExists returned unexpectedly\n";
+ }
+ else
+ {
+ std::cout << "TestYieldFunctionNotExits expected error: " << ec << "\n";
+ }
}
int server()
@@ -317,6 +339,25 @@
"xyz.openbmc_project.ObjectMapper", "GetSubTree",
"/org/openbmc/control", 2, std::vector<std::string>());
+ conn->async_method_call(
+ [](boost::system::error_code ec,
+ const std::vector<std::string>& things) {
+ std::cout << "async_method_call callback\n";
+ if (ec)
+ {
+ std::cerr << "async_method_call expected failure: " << ec
+ << "\n";
+ }
+ else
+ {
+ std::cerr << "asyn_method_call should have faild!\n";
+ }
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/sensors", depth, interfaces);
+
// sd_events work too using the default event loop
phosphor::Timer t1([]() { std::cerr << "*** tock ***\n"; });
t1.start(std::chrono::microseconds(1000000));