You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DevOps SDK递归检查Project/CR Id一致性遇报错求助

Azure DevOps Python SDK 字段一致性校验问题修复

问题场景

通过Azure DevOps Python SDK递归获取用户故事及其所有层级子测试用例的Project/CR Id字段值,校验字段是否存在且一致时,出现两类错误:

  • TypeError: 'NoneType' object is not iterable
  • NameError: name 'consistent' is not defined

报错原因分析

  1. TypeError 原因:递归遍历子工作项时,部分子工作项的relations属性可能为None,直接执行for relation in item.relations会触发迭代None的错误。
  2. NameError 原因:consistent和cr_or_project_value变量在try块内部定义,当try块抛出异常时,这两个变量未被初始化,后续代码引用时就会触发未定义错误。

修复后的完整代码

import os
import re
from azure.devops.connection import Connection
from msrest.authentication import BasicAuthentication

# 替换为实际的PAT和组织URL
personal_access_token = 'PAT'
organization_url = 'https://dev.azure.com/**'
work_item_id = 123  # 替换为实际工作项ID

# 创建组织连接
credentials = BasicAuthentication('', personal_access_token)
connection = Connection(base_url=organization_url, creds=credentials)

# 获取工作项跟踪客户端
work_item_tracking_client = connection.clients.get_work_item_tracking_client()

def check_project_cr_ids_consistency(work_item):
    project_cr_ids_consistent = True
    project_cr_id_value = None
    
    def recursive_check(item):
        nonlocal project_cr_ids_consistent, project_cr_id_value
        
        # 检查字段是否存在且非空
        if 'Custom.ProjectorCRId' in item.fields:
            current_project_cr_id_value = item.fields['Custom.ProjectorCRId']
            
            if current_project_cr_id_value.strip() == "":
                project_cr_ids_consistent = False
            elif project_cr_id_value is None:
                project_cr_id_value = current_project_cr_id_value
            elif project_cr_id_value != current_project_cr_id_value:
                project_cr_ids_consistent = False
        else:
            project_cr_ids_consistent = False
        
        # 修复:先判断relations是否存在且非空,再遍历
        if hasattr(item, 'relations') and item.relations is not None:
            for relation in item.relations:
                if relation.rel == 'System.LinkTypes.Hierarchy-Forward':
                    child_id = int(relation.url.split('/')[-1])
                    child_work_items = work_item_tracking_client.get_work_items(ids=[child_id])
                    
                    for child_work_item in child_work_items:
                        recursive_check(child_work_item)
    
    recursive_check(work_item)
    
    return (project_cr_ids_consistent, project_cr_id_value)

# 初始化变量,避免异常时未定义
consistent = False
cr_or_project_value = None

try:
    # 获取工作项详情,包含关联关系
    work_item = work_item_tracking_client.get_work_item(id=work_item_id, expand='all')
    
    title = work_item.fields['System.Title']
    print(f"标题: {title}")
   
    consistent, cr_or_project_value = check_project_cr_ids_consistency(work_item) 

except Exception as e :
    print(f"发生错误: {e}")

# 后续逻辑可以正常执行,因为变量已初始化
print(f"Project/CR IDs 一致性: {consistent}")
if not consistent :
    print("检测到子项中存在不一致的Project/CR IDs。")
else :
   print(f"一致的Project/CR ID 值: {cr_or_project_value}")

# 避免cr_or_project_value为None时触发正则错误
if cr_or_project_value is not None:
    pattern = re.compile(r'\b' + re.escape(cr_or_project_value) + r'\b')
    match = pattern.search(title)
    print(bool(match))
else:
    print("无有效Project/CR ID可匹配标题")

关键修复点

  • 修复TypeError:在遍历item.relations前,增加item.relations is not None的判断,确保只有非空的relations才会被迭代。
  • 修复NameError:在try块外提前初始化consistent和cr_or_project_value变量,确保无论try块是否抛出异常,后续代码都能正常引用。
  • 额外优化:增加对cr_or_project_value为None的判断,避免正则编译时出现错误。

内容的提问来源于stack exchange,提问作者Salman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 02:34:53