tfsaggregator / aggregator-cli

A new version of Aggregator aiming at Azure DevOps (ex Visual Studio Team Services)
https://tfsaggregator.github.io/
Apache License 2.0
73 stars 32 forks source link

Problems with Null Values in a custom field #185

Closed jprettyman closed 3 years ago

jprettyman commented 4 years ago

I have a custom field and want to set the value for children to the same as self. In some cases, the self value is null. This causes a save problem.

[2020-09-15 14:07:11Z] [{"Code":400,"Headers":{"Content-Type":"application/json; charset=utf-8"},"Body":"{\"count\":1,\"value\":{\"Message\":\"Value cannot be null.\"}}"},{"Code":400,"Headers":{"Content-Type":"application/json; charset=utf-8"},"Body":"{\"count\":1,\"value\":{\"Message\":\"Value cannot be null.\"}}"},{"Code":400,"Headers":{"Content-Type":"application/json; charset=utf-8"},"Body":"{\"count\":1,\"value\":{\"Message\":\"Value cannot be null.\"}}"}]
[2020-09-15 14:07:11Z] Save failed: {"count":1,"value":{"Message":"Value cannot be null."}}

If I wrap it in a statement, things work OK

if (child["MyCo.Common.MyField"] != null ) { child["MyCo.Common.MyField"] = self["MyCo.Common.MyField"]; }

if I use it direct, I get the message above if the self value is null.

child["MyCo.Common.MyField"] = self["MyCo.Common.MyField"];

Is there a clean way of handling null values without wrapping fields in an if statement?

giuliov commented 3 years ago

What happens behind the scene Azure DevOps returns only fields with a value. To prevent exceptions, when a field is read, the private GetFieldValue method checks if there is a value, otherwise it returns a default value for the field type. Custom fields type is object unless you use the public GetFieldValue method or a cast. This means that a missing custom field has value null. When SetFieldValue is called from the assignment operator, it records an change operation with the new value. When the Rule completes, all change operations are sent to Azure DevOps.

Solutions

  1. Guard the assignment with an if != null. This is a bit cumbersome, but can implemented within a Rule. This what you used
  2. Change SetFieldValue behaviour to skip null assignments.
  3. Change SetFieldValue behaviour to use a remove operation when value is null. This will remove any value on the target.

I am leaning on the latter, but I would like some feedback from you (and @jessehouwing)

jprettyman commented 3 years ago

After reviewing your response, I agree that removing the value for Nulls would be the most appropriate action. If the user keys in valA = valB; and valB is null, make valA null. the only way to do this is to initiate a remove action within the SetFieldValue.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.