Skip to content

Commit

Permalink
union UPDATE get errors of all the types
Browse files Browse the repository at this point in the history
Fixes #2071
  • Loading branch information
michalvasko committed Aug 8, 2023
1 parent 30e75a7 commit e2c8fb8
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 6 deletions.
39 changes: 34 additions & 5 deletions src/plugins_types/union.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ union_store_type(const struct ly_ctx *ctx, struct lysc_type *type, struct lyd_va
const void *value = NULL;
size_t value_len = 0;

*err = NULL;

if (subvalue->format == LY_VALUE_LYB) {
lyb_parse_union(subvalue->original, subvalue->orig_len, NULL, &value, &value_len);
} else {
Expand Down Expand Up @@ -220,36 +222,63 @@ union_find_type(const struct ly_ctx *ctx, struct lysc_type **types, struct lyd_v
{
LY_ERR ret = LY_SUCCESS;
LY_ARRAY_COUNT_TYPE u;
struct ly_err_item **errs = NULL, *e;
uint32_t temp_lo = 0;
char *msg = NULL;
int msg_len = 0;

if (!types || !LY_ARRAY_COUNT(types)) {
return LY_EINVAL;
}

*err = NULL;

/* alloc errors */
errs = calloc(LY_ARRAY_COUNT(types), sizeof *errs);
LY_CHECK_RET(!errs, LY_EMEM);

/* turn logging temporarily off */
ly_temp_log_options(&temp_lo);

/* use the first usable subtype to store the value */
for (u = 0; u < LY_ARRAY_COUNT(types); ++u) {
ret = union_store_type(ctx, types[u], subvalue, resolve, ctx_node, tree, unres, err);
ret = union_store_type(ctx, types[u], subvalue, resolve, ctx_node, tree, unres, &e);
if ((ret == LY_SUCCESS) || (ret == LY_EINCOMPLETE)) {
break;
}

ly_err_free(*err);
*err = NULL;
errs[u] = e;
}

if (u == LY_ARRAY_COUNT(types)) {
ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Invalid union value \"%.*s\" - no matching subtype found.",
/* create the full error */
msg_len = asprintf(&msg, "Invalid union value \"%.*s\" - no matching subtype found:\n",
(int)subvalue->orig_len, (char *)subvalue->original);
if (msg_len == -1) {
LY_CHECK_ERR_GOTO(!errs, ret = LY_EMEM, cleanup);
}
for (u = 0; u < LY_ARRAY_COUNT(types); ++u) {
if (!errs[u]) {
/* no error for some reason */
continue;
}

msg = ly_realloc(msg, msg_len + 4 + strlen(types[u]->plugin->id) + 2 + strlen(errs[u]->msg) + 2);
LY_CHECK_ERR_GOTO(!msg, ret = LY_EMEM, cleanup);
msg_len += sprintf(msg + msg_len, " %s: %s\n", types[u]->plugin->id, errs[u]->msg);
}

ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "%s", msg);
} else if (type_idx) {
*type_idx = u;
}

/* restore logging */
cleanup:
for (u = 0; u < LY_ARRAY_COUNT(types); ++u) {
ly_err_free(errs[u]);
}
free(errs);
free(msg);
ly_temp_log_options(NULL);
return ret;
}
Expand Down
7 changes: 6 additions & 1 deletion tests/utests/types/union.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,12 @@ test_data_xml(void **state)
/* invalid value */
TEST_ERROR_XML2("",
"defs", "", "un1", "123456789012345678901", LY_EVALID);
CHECK_LOG_CTX("Invalid union value \"123456789012345678901\" - no matching subtype found.",
CHECK_LOG_CTX("Invalid union value \"123456789012345678901\" - no matching subtype found:\n"
" libyang 2 - leafref, version 1: Invalid type int8 value \"123456789012345678901\".\n"
" libyang 2 - leafref, version 1: Invalid type int64 value \"123456789012345678901\".\n"
" libyang 2 - identityref, version 1: Invalid identityref \"123456789012345678901\" value - identity not found in module \"defs\".\n"
" libyang 2 - instance-identifier, version 1: Invalid instance-identifier \"123456789012345678901\" value - syntax error.\n"
" libyang 2 - string, version 1: Unsatisfied length - string \"123456789012345678901\" length is not allowed.\n",
"Schema location \"/defs:un1\", line number 1.");
}

Expand Down

0 comments on commit e2c8fb8

Please sign in to comment.