ballerina-platform / ballerina-library

The Ballerina Library
https://ballerina.io/learn/api-docs/ballerina/
Apache License 2.0
137 stars 58 forks source link

Improve the JSON output format for error fields in the fromBytes() API of the copybook #6990

Open MohamedSabthar opened 2 weeks ago

MohamedSabthar commented 2 weeks ago

Description: Currently, if there are any partial errors while parsing the copybook, they are added to the payload in the following format:

{
  "data": {
    "root": {
      "child": {
        "leaf1": "data",
        "leaf2": null // This is null due to errors
      }
    },
    "errors": [
      "Failed to convert value 'ABC' to decimal at '$.root.child.leaf2'."
    ]
  }
}

Instead of returning errors as shown above, we could improve the error portion of the payload and return a payload like this:

{
  "data": {
    "root": {
      "child": {
        "leaf1": "data",
        "leaf2": null // This is null due to errors
      }
    },
    "errors": {
      "root": {
        "child": {
          "leaf2": "Failed to convert value 'ABC' to decimal."
        }
      }
    }
  }
}

This would allow the user to easily obtain the errors of specific fields without doing much manual work.

Describe your solution(s) following sample algorithm will map the current output the described format.

import ballerina/io;

public function main() {
    string[] errorPaths = ["$.root.child1.leaf1", "$.root.child1.leaf2", "$.root.leaf3"];
    string[] errorVals = ["failed leaf 1", "failed leaf 2", "failed leaf 3"];

    map<json> errors = {};
    json parent = errors;
    foreach int i in 0 ..< errorPaths.length() {
        string[] pathFragments = re `\.`.split(errorPaths[i]);
        while pathFragments.length() != 0 {
            string fragment = pathFragments.shift();
            if fragment == "$" {
                parent = errors;
                continue;
            }
            if parent is map<json> && !parent.hasKey(fragment) {
                parent[fragment] = pathFragments.length() == 0 ? errorVals[i] : {};
                parent = parent.get(fragment);
            } else if parent is map<json> {
                parent = parent.get(fragment);
            }
        }
    }
    io:println(errors);
}

Related Issues (optional):

Suggested Labels (optional):

Suggested Assignees (optional):