diff --git a/CHANGELOG.md b/CHANGELOG.md
index cfc98c42..8a0ddc86 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,7 +12,7 @@
* Get it with `clicon_nsctx_global_get(h)`
* Added wildcard `*` as a mode to `CLICON_MODE` in clispec files
* If you set "CLICON_MODE="*";" in a clispec file it means that syntax will appear in all CLI spec modes.
-* State callbacks provided by user are validated. If they are invalid an internal error is returned.
+* State callbacks provided by user are validated. If they are invalid an internal error is returned, example, with error-tag: `operation-failed`and with error-message containing. `Internal error, state callback returned invalid XML`.
* Fixed multi-namespace for augmented state which was not covered in 4.2.0.
### API changes on existing features (you may need to change your code)
diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c
index 6ca91325..1dde1a65 100644
--- a/apps/backend/backend_plugin.c
+++ b/apps/backend/backend_plugin.c
@@ -134,19 +134,25 @@ clixon_plugin_statedata(clicon_handle h,
if (ret > 0 && (ret = xml_yang_validate_add(h, x, &xerr)) < 0)
goto done;
if (ret == 0){
- if ((cberr = cbuf_new()) ==NULL){
- clicon_err(OE_XML, errno, "cbuf_new");
- goto done;
+ cxobj *xe;
+ cxobj *xb;
+
+ if ((xe = xpath_first(xerr, NULL, "//error-tag")) != NULL &&
+ (xb = xml_body_get(xe))){
+ if (xml_value_set(xb, "operation-failed") < 0)
+ goto done;
+ }
+ if ((xe = xpath_first(xerr, NULL, "//error-message")) != NULL &&
+ (xb = xml_body_get(xe))){
+ if (xml_value_append(xb, " Internal error, state callback returned invalid XML") < 0)
+ goto done;
}
- cprintf(cberr, "Internal error: state callback returned invalid XML: ");
- if (netconf_err2cb(xpath_first(xerr, NULL, "rpc-error"), cberr) < 0)
- goto done;
if (*xret){
xml_free(*xret);
*xret = NULL;
}
- if (netconf_operation_failed_xml(xret, "application", cbuf_get(cberr))< 0)
- goto done;
+ *xret = xerr;
+ xerr = NULL;
goto fail;
}
#if 1
diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c
index 54b9072d..040d65eb 100644
--- a/lib/src/clixon_netconf_lib.c
+++ b/lib/src/clixon_netconf_lib.c
@@ -953,7 +953,7 @@ netconf_operation_not_supported(cbuf *cb,
* some reason not covered by any other error condition.
* @param[out] cb CLIgen buf. Error XML is written in this buffer
* @param[in] type Error type: "rpc", "application" or "protocol"
- * @param[in] message Error message
+ * @param[in] message Error message (will be XML encoded)
* @see netconf_operation_failed_xml Same but returns XML tree
*/
int
@@ -994,6 +994,7 @@ int
netconf_operation_failed_xml(cxobj **xret,
char *type,
char *message)
+
{
int retval =-1;
cxobj *xerr;
@@ -1009,7 +1010,8 @@ netconf_operation_failed_xml(cxobj **xret,
goto done;
if (xml_parse_va(&xerr, NULL, "%s"
"operation-failed"
- "error", type) < 0)
+ "error",
+ type) < 0)
goto done;
if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0)
diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c
index 2caaea91..63daa827 100644
--- a/lib/src/clixon_xml_map.c
+++ b/lib/src/clixon_xml_map.c
@@ -1274,13 +1274,27 @@ xml_yang_validate_all(clicon_handle h,
int nr;
int ret;
cxobj *x;
+ char *namespace = NULL;
+ cbuf *cb = NULL;
/* if not given by argument (overide) use default link
and !Node has a config sub-statement and it is false */
ys=xml_spec(xt);
if (ys==NULL){
- if (netconf_unknown_element_xml(xret, "application", xml_name(xt), NULL) < 0)
+ if ((cb = cbuf_new()) == NULL){
+ clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
+ }
+ if (xml2ns(xt, xml_prefix(xt), &namespace) < 0)
+ goto done;
+ if (namespace){
+ cprintf(cb, "namespace is: %s", namespace);
+ if (netconf_unknown_element_xml(xret, "application", xml_name(xt), cbuf_get(cb)) < 0)
+ goto done;
+ }
+ else
+ if (netconf_unknown_element_xml(xret, "application", xml_name(xt), NULL) < 0)
+ goto done;
goto fail;
}
if (yang_config(ys) != 0){
@@ -1326,7 +1340,7 @@ xml_yang_validate_all(clicon_handle h,
goto done;
if (!nr){
ye = yang_find(yc, Y_ERROR_MESSAGE, NULL);
- if (netconf_operation_failed_xml(xret, "application",
+ if (netconf_operation_failed_xml(xret, "application",
ye?ye->ys_argument:"must xpath validation failed") < 0)
goto done;
goto fail;
@@ -1338,7 +1352,7 @@ xml_yang_validate_all(clicon_handle h,
if ((nr = xpath_vec_bool(xt, NULL, "%s", xpath)) < 0)
goto done;
if (!nr){
- if (netconf_operation_failed_xml(xret, "application",
+ if (netconf_operation_failed_xml(xret, "application",
"when xpath validation failed") < 0)
goto done;
goto fail;
@@ -1363,6 +1377,8 @@ xml_yang_validate_all(clicon_handle h,
ok:
retval = 1;
done:
+ if (cb)
+ cbuf_free(cb);
return retval;
fail:
retval = 0;