Summary
In connection.hpp, yield_method_call unconditionally calls
message_t::unpack() on the reply even when the underlying async_send
failed. Since unpack() will throw on a non-success / error reply, the
catch (...) block replaces the original (meaningful) error code with
boost::system::errc::invalid_argument, masking the real failure cause.
Location
File: include/sdbusplus/asio/connection.hpp
Function: yield_method_call
Lines (approx): 276-289
if (!ec)
{
message_t r;
r = async_send_yield(m, yield[ec]);
try
{
return r.unpack<RetTypes...>();
}
catch (const std::exception&)
{
ec = boost::system::errc::make_error_code(
boost::system::errc::invalid_argument);
}
}
When async_send fails (e.g. D-Bus method error, timeout, connection error), the returned message_t r is either the original request message (synchronous failure path in async_send_handler::operator(), where the handler is invoked with mesg) or a METHOD_ERROR reply. Neither can be unpacked into RetTypes..., so unpack() throws, the catch (...) block runs, and ec is overwritten with invalid_argument.
As a result the caller cannot distinguish between:
a transport / D-Bus level failure (timeout, ENOENT, ETIMEDOUT, method error, ...), and
an actual return-value deserialization failure.
All real error diagnostics are lost, which makes diagnosing issues in the field very difficult.
Suggested fix
if (!ec)
{
message_t r;
r = async_send_yield(m, yield[ec]);
if (!ec)
{
try
{
return r.unpack<RetTypes...>();
}
catch (const std::exception&)
{
ec = boost::system::errc::make_error_code(
boost::system::errc::invalid_argument);
}
}
}
This brings the behavior in line with async_method_call_timed and preserves the real error code on transport / D-Bus level failures.
Summary
In
connection.hpp,yield_method_callunconditionally callsmessage_t::unpack()on the reply even when the underlyingasync_sendfailed. Since
unpack()will throw on a non-success / error reply, thecatch (...)block replaces the original (meaningful) error code withboost::system::errc::invalid_argument, masking the real failure cause.Location
File:
include/sdbusplus/asio/connection.hppFunction:
yield_method_callLines (approx): 276-289
When async_send fails (e.g. D-Bus method error, timeout, connection error), the returned message_t r is either the original request message (synchronous failure path in async_send_handler::operator(), where the handler is invoked with mesg) or a METHOD_ERROR reply. Neither can be unpacked into RetTypes..., so unpack() throws, the catch (...) block runs, and ec is overwritten with invalid_argument.
As a result the caller cannot distinguish between:
a transport / D-Bus level failure (timeout, ENOENT, ETIMEDOUT, method error, ...), and
an actual return-value deserialization failure.
All real error diagnostics are lost, which makes diagnosing issues in the field very difficult.
Suggested fix
This brings the behavior in line with async_method_call_timed and preserves the real error code on transport / D-Bus level failures.