Skip to content

Commit 01eb5d2

Browse files
committed
Fix exceptions mapped by map_exception_to_dbus_error not translating from Python to D-Bus
This fixes the Python built-in exceptions not being translated when raised by sdbus server. Also the mapped exceptions will have their first argument added to the error message as string.
1 parent d7973e4 commit 01eb5d2

File tree

4 files changed

+24
-14
lines changed

4 files changed

+24
-14
lines changed

src/sdbus/dbus_proxy_async_method.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
DbusRemoteObjectMeta,
3434
)
3535
from .dbus_exceptions import DbusFailedError
36-
from .sd_bus_internals import DbusNoReplyFlag
36+
from .sd_bus_internals import EXCEPTION_TO_DBUS_ERROR, DbusNoReplyFlag
3737

3838
if TYPE_CHECKING:
3939
from collections.abc import Callable, Sequence
@@ -193,23 +193,20 @@ async def _dbus_reply_call(
193193
request_message,
194194
local_object,
195195
)
196-
except DbusFailedError as e:
196+
except Exception as e:
197197
if not request_message.expect_reply:
198198
return
199199

200+
dbus_error = EXCEPTION_TO_DBUS_ERROR.get(type(e))
201+
if dbus_error is None:
202+
dbus_error = DbusFailedError.dbus_error_name
203+
200204
error_message = request_message.create_error_reply(
201-
e.dbus_error_name,
205+
dbus_error,
202206
str(e.args[0]) if e.args else "",
203207
)
204208
error_message.send()
205209
return
206-
except Exception:
207-
error_message = request_message.create_error_reply(
208-
DbusFailedError.dbus_error_name,
209-
"",
210-
)
211-
error_message.send()
212-
return
213210

214211
if not request_message.expect_reply:
215212
return

src/sdbus/sd_bus_internals.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,9 @@ class SdBusRequestNameAlreadyOwnerError(SdBusRequestNameError):
304304
...
305305

306306

307-
DBUS_ERROR_TO_EXCEPTION: dict[str, Exception] = {}
307+
DBUS_ERROR_TO_EXCEPTION: dict[str, type[Exception]] = {}
308308

309-
EXCEPTION_TO_DBUS_ERROR: dict[Exception, str] = {}
309+
EXCEPTION_TO_DBUS_ERROR: dict[type[Exception], str] = {}
310310

311311
DbusDeprecatedFlag: int = 0
312312
DbusHiddenFlag: int = 0

src/sdbus/sd_bus_internals_funcs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ static PyObject* map_exception_to_dbus_error(PyObject* Py_UNUSED(self), PyObject
144144

145145
#endif
146146
if (CALL_PYTHON_INT_CHECK(PyDict_Contains(dbus_error_to_exception_dict, dbus_error_string)) > 0) {
147-
PyErr_Format(PyExc_ValueError, "Dbus error %R is already mapped.", dbus_error_string);
147+
PyErr_Format(PyExc_ValueError, "D-Bus error %R is already mapped.", dbus_error_string);
148148
return NULL;
149149
}
150150

@@ -166,7 +166,7 @@ static PyObject* add_exception_mapping(PyObject* Py_UNUSED(self), PyObject* args
166166
PyObject* dbus_error_string CLEANUP_PY_OBJECT = CALL_PYTHON_AND_CHECK(PyObject_GetAttrString(exception, "dbus_error_name"));
167167

168168
if (CALL_PYTHON_INT_CHECK(PyDict_Contains(dbus_error_to_exception_dict, dbus_error_string)) > 0) {
169-
PyErr_Format(PyExc_ValueError, "Dbus error %R is already mapped.", dbus_error_string);
169+
PyErr_Format(PyExc_ValueError, "D-Bus error %R is already mapped.", dbus_error_string);
170170
return NULL;
171171
}
172172

test/test_sdbus_async.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ async def raise_and_unmap_error(self) -> None:
196196

197197
raise DbusErrorUnmappedLater('Should be unmapped')
198198

199+
@dbus_method_async()
200+
async def raise_python_exc(self) -> None:
201+
raise ValueError("Test!")
202+
199203
@dbus_method_async('s', flags=DbusNoReplyFlag)
200204
async def no_reply_method(self, new_value: str) -> None:
201205
self.no_reply_sync.set()
@@ -1004,3 +1008,12 @@ async def test() -> None:
10041008

10051009
with self.assertRaisesRegex(RuntimeError, "different loop"):
10061010
asyncio_run(test())
1011+
1012+
async def test_python_exc(self) -> None:
1013+
test_object, test_object_connection = initialize_object()
1014+
1015+
with self.assertRaisesRegex(ValueError, "Test!"):
1016+
await test_object.raise_python_exc()
1017+
1018+
with self.assertRaisesRegex(ValueError, "Test!"):
1019+
await test_object_connection.raise_python_exc()

0 commit comments

Comments
 (0)