Repository: microsoft/onefuzz
File: src/ApiService/ApiService/onefuzzlib/notifications/Ado.cs (C#)

Code before:
                return OneFuzzResultVoid.Error(ErrorCode.NOTIFICATION_FAILURE,
                    $"Failed to process ado notification : exception: {e}");
            }
        }
        return OneFuzzResultVoid.Ok;
    }

    private static bool IsTransient(Exception e) {
        var errorCodes = new List<string>()
        {
            //TF401349: An unexpected error has occurred, please verify your request and try again.
            "TF401349",
            //TF26071: This work item has been changed by someone else since you opened it. You will need to refresh it and discard your changes.
            "TF26071",
        };

        var errorStr = e.ToString();
        return errorCodes.Any(errorStr.Contains);
    }

    private static async Async.Task<OneFuzzResultVoid> ValidatePath(string project, string path, TreeStructureGroup structureGroup, WorkItemTrackingHttpClient client) {
        var pathParts = path.Split('\\');
        if (pathParts[0] != project) {
            return OneFuzzResultVoid.Error(ErrorCode.ADO_VALIDATION_INVALID_PATH, new string[] {
                $"Path \"{path}\" is invalid. It must start with the project name, \"{project}\".",
                $"Example: \"{project}\\{path}\".",
            });
        }

        var current = await client.GetClassificationNodeAsync(project, structureGroup, depth: pathParts.Length - 1);
        if (current == null) {
            return OneFuzzResultVoid.Error(ErrorCode.ADO_VALIDATION_INVALID_PATH, new string[] {
                $"Path \"{path}\" is invalid. \"{project}\" is not a valid project.",
            });
        }

        foreach (var part in pathParts.Skip(1)) {
            var child = current.Children?.FirstOrDefault(x => x.Name == part);
            if (child == null) {
                return OneFuzzResultVoid.Error(ErrorCode.ADO_VALIDATION_INVALID_PATH, new string[] {
                    $"Path \"{path}\" is invalid. \"{part}\" is not a valid child of \"{current.Name}\".",
                    $"Valid children of \"{current.Name}\" are: [{string.Join(',', current.Children?.Select(x => $"\"{x.Name}\"") ?? new List<string>())}].",
                });
            }

            current = child;
        }

        return OneFuzzResultVoid.Ok;
    }


Review comment (suggestion):
We know at this point if we're validating an area of iteration path based on the structureGroup so we could include that in the error message. Ex: `Area Path \"{path}\" is invalid` or `Iteration Path ...`

Code after:
                return OneFuzzResultVoid.Error(ErrorCode.NOTIFICATION_FAILURE,
                    $"Failed to process ado notification : exception: {e}");
            }
        }
        return OneFuzzResultVoid.Ok;
    }

    private static bool IsTransient(Exception e) {
        var errorCodes = new List<string>()
        {
            //TF401349: An unexpected error has occurred, please verify your request and try again.
            "TF401349",
            //TF26071: This work item has been changed by someone else since you opened it. You will need to refresh it and discard your changes.
            "TF26071",
        };

        var errorStr = e.ToString();
        return errorCodes.Any(errorStr.Contains);
    }

    private static async Async.Task<OneFuzzResultVoid> ValidatePath(string project, string path, TreeStructureGroup structureGroup, WorkItemTrackingHttpClient client) {
        var pathType = (structureGroup == TreeStructureGroup.Areas) ? "Area" : "Iteration";
        var pathParts = path.Split('\\');
        if (!string.Equals(pathParts[0], project, StringComparison.OrdinalIgnoreCase)) {
            return OneFuzzResultVoid.Error(ErrorCode.ADO_VALIDATION_INVALID_PATH, new string[] {
                $"Path \"{path}\" is invalid. It must start with the project name, \"{project}\".",
                $"Example: \"{project}\\{path}\".",
            });
        }

        var current = await client.GetClassificationNodeAsync(project, structureGroup, depth: pathParts.Length - 1);
        if (current == null) {
            return OneFuzzResultVoid.Error(ErrorCode.ADO_VALIDATION_INVALID_PATH, new string[] {
                $"{pathType} Path \"{path}\" is invalid. \"{project}\" is not a valid project.",
            });
        }

        foreach (var part in pathParts.Skip(1)) {
            var child = current.Children?.FirstOrDefault(x => string.Equals(x.Name, part, StringComparison.OrdinalIgnoreCase));
            if (child == null) {
                return OneFuzzResultVoid.Error(ErrorCode.ADO_VALIDATION_INVALID_PATH, new string[] {
                    $"{pathType} Path \"{path}\" is invalid. \"{part}\" is not a valid child of \"{current.Name}\".",
                    $"Valid children of \"{current.Name}\" are: [{string.Join(',', current.Children?.Select(x => $"\"{x.Name}\"") ?? new List<string>())}].",
                });
            }

            current = child;
        }

        return OneFuzzResultVoid.Ok;
    }