Skip to content

Commit d28a495

Browse files
committed
session: forward error code to client
Since sysrepo 2.2.170, the return code of application callbacks is ignored if they called sr_session_set_error_message() to report error details. Instead, a generic SR_ERR_OPERATION_FAILED code is attached with multiple error messages. Since we have the possibility to do it, attach specific error codes using sr_session_set_error() instead. Adjust unit tests accordingly. Link: sysrepo/sysrepo@282926f1d0d66 Signed-off-by: Robin Jarry <[email protected]>
1 parent ccd84b0 commit d28a495

File tree

4 files changed

+25
-13
lines changed

4 files changed

+25
-13
lines changed

cffi/cdefs.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ int sr_session_switch_ds(sr_session_ctx_t *, sr_datastore_t);
9595
sr_datastore_t sr_session_get_ds(sr_session_ctx_t *);
9696
sr_conn_ctx_t *sr_session_get_connection(sr_session_ctx_t *);
9797
int sr_session_get_error(sr_session_ctx_t *, const sr_error_info_t **);
98-
int sr_session_set_error_message(sr_session_ctx_t *, const char *, ...);
98+
int sr_session_set_error(sr_session_ctx_t *, const char *, sr_error_t, const char *, ...);
9999
const char *sr_session_get_orig_name(sr_session_ctx_t *session);
100100
int sr_session_set_orig_name(sr_session_ctx_t *session, const char *);
101101
int sr_session_get_orig_data(sr_session_ctx_t *session, uint32_t idx, uint32_t *size, const void **data);

sysrepo/session.py

+16-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from _sysrepo import ffi, lib
1212
from .change import Change
1313
from .errors import (
14+
SysrepoError,
1415
SysrepoInternalError,
1516
SysrepoNotFoundError,
1617
SysrepoUnsupportedError,
@@ -164,7 +165,7 @@ def switch_datastore(self, datastore: str) -> None:
164165
ds = datastore_value(datastore)
165166
check_call(lib.sr_session_switch_ds, self.cdata, ds)
166167

167-
def set_error(self, message: str):
168+
def set_error(self, err: BaseException):
168169
"""
169170
Set detailed error information into provided session. Used to notify the client
170171
library about errors that occurred in the application code. Does not print the
@@ -173,13 +174,24 @@ def set_error(self, message: str):
173174
Intended for change, RPC/action, or operational callbacks to be used on the
174175
provided session.
175176
176-
:arg str message:
177-
The detailed error message.
177+
:arg BaseException err:
178+
The python exception object that carries the error information.
178179
"""
179180
if not self.is_implicit:
180181
raise SysrepoUnsupportedError("can only report errors on implicit sessions")
182+
if isinstance(err, SysrepoError):
183+
code = err.rc
184+
message = err.msg
185+
else:
186+
code = lib.SR_ERR_CALLBACK_FAILED
187+
message = str(err)
181188
check_call(
182-
lib.sr_session_set_error_message, self.cdata, str2c("%s"), str2c(message)
189+
lib.sr_session_set_error,
190+
self.cdata,
191+
ffi.NULL,
192+
code,
193+
str2c("%s"),
194+
str2c(message),
183195
)
184196

185197
def get_originator_name(self) -> str:

sysrepo/subscription.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ def module_change_callback(session, sub_id, module, xpath, event, req_id, priv):
304304
and isinstance(session, SysrepoSession)
305305
and isinstance(xpath, str)
306306
):
307-
session.set_error(e.msg)
307+
session.set_error(e)
308308
return e.rc
309309

310310
except BaseException as e:
@@ -317,7 +317,7 @@ def module_change_callback(session, sub_id, module, xpath, event, req_id, priv):
317317
and isinstance(session, SysrepoSession)
318318
and isinstance(xpath, str)
319319
):
320-
session.set_error(str(e))
320+
session.set_error(e)
321321
return lib.SR_ERR_CALLBACK_FAILED
322322

323323

@@ -421,7 +421,7 @@ def oper_data_callback(session, sub_id, module, xpath, req_xpath, req_id, parent
421421

422422
except SysrepoError as e:
423423
if e.msg and isinstance(session, SysrepoSession) and isinstance(xpath, str):
424-
session.set_error(e.msg)
424+
session.set_error(e)
425425
return e.rc
426426

427427
except BaseException as e:
@@ -430,7 +430,7 @@ def oper_data_callback(session, sub_id, module, xpath, req_xpath, req_id, parent
430430
# We are in a C callback, we cannot let any error pass
431431
LOG.exception("%r callback failed", locals().get("callback", priv))
432432
if isinstance(session, SysrepoSession) and isinstance(xpath, str):
433-
session.set_error(str(e))
433+
session.set_error(e)
434434
return lib.SR_ERR_CALLBACK_FAILED
435435

436436

@@ -548,7 +548,7 @@ def rpc_callback(session, sub_id, xpath, input_node, event, req_id, output_node,
548548

549549
except SysrepoError as e:
550550
if e.msg and isinstance(session, SysrepoSession) and isinstance(xpath, str):
551-
session.set_error(e.msg)
551+
session.set_error(e)
552552
return e.rc
553553

554554
except BaseException as e:
@@ -557,7 +557,7 @@ def rpc_callback(session, sub_id, xpath, input_node, event, req_id, output_node,
557557
# We are in a C callback, we cannot let any error pass
558558
LOG.exception("%r callback failed", locals().get("callback", priv))
559559
if isinstance(session, SysrepoSession) and isinstance(xpath, str):
560-
session.set_error(str(e))
560+
session.set_error(e)
561561
return lib.SR_ERR_CALLBACK_FAILED
562562

563563

tests/test_subs_module_change.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def module_change_cb(event, req_id, changes, private_data):
7474
# 2.
7575
sent_config = {"conf": {"system": {"hostname": "INVALID"}}}
7676
expected_changes = []
77-
with self.assertRaises(sysrepo.SysrepoCallbackFailedError):
77+
with self.assertRaises(sysrepo.SysrepoValidationFailedError):
7878
ch_sess.replace_config(sent_config, "sysrepo-example", strict=True)
7979
# 3.
8080
sent_config = {
@@ -347,7 +347,7 @@ def module_change_cb(session, event, req_id, private_data):
347347
# 2.
348348
sent_config = {"conf": {"system": {"hostname": "INVALID"}}}
349349
expected_changes = []
350-
with self.assertRaises(sysrepo.SysrepoCallbackFailedError):
350+
with self.assertRaises(sysrepo.SysrepoValidationFailedError):
351351
ch_sess.replace_config(sent_config, "sysrepo-example", strict=True)
352352
# 3.
353353
sent_config = {

0 commit comments

Comments
 (0)