Node.js获取Azure DevOps工作项详情报错求助
问题描述
我有一个Node.js应用,可创建和获取Azure DevOps工单,创建功能正常,但通过标题查询工作项详情时出现错误。以下是我的查询方法代码,同时附上错误截图:
async function getWorkItemIdByTitle(workItemTitle) { let status = ""; console.log("getting work item ID") console.log(workItemTitle); try { // Encode the title for the URL const encodedTitle = encodeURIComponent(workItemTitle); // Construct the query URL to search for work items by title const url = `${orgUrl}/${projectNameForURL}/_apis/wit/wiql?api-version=7.1`; // WIQL (Work Item Query Language) query to search for work items by title const wiqlQuery = `SELECT [System.Id] FROM WorkItems WHERE [System.Title] = '${encodedTitle}'`; const response = await axios.post(url, { query: wiqlQuery }, { headers: { 'Content-Type': 'application/json-patch+json', 'Authorization': `Basic ${Buffer.from(`:${pat}`).toString('base64')}`, }, }); // Check if any work items were found if (response.data.workItems.length > 0) { const workItemId = response.data.workItems[0].id; console.log(`Work item ID for title '${workItemTitle}': ${workItemId}`); status = "Incident Number: " + workItemId; } else { console.log(`No work item found with title '${workItemTitle}'`); status = "No matching incidents found" } } catch (error) { console.error('Error retrieving work item by title:', error.response ? error.response.data : error.message); status = "Error fetching incidents"; } console.log("STATUS: ", status); return status; }
错误截图:
修复方案
从错误信息和代码来看,有3个核心问题需要修正:
Content-Type 头部错误
WIQL查询接口要求的Content-Type是application/json,而你使用的application/json-patch+json是用于更新工作项的接口,这会导致请求格式不被识别。WIQL查询的编码逻辑错误
你对标题做了encodeURIComponent后直接拼到WIQL语句里,会导致标题被双重编码,比如空格会变成%20,但WIQL里需要的是原始空格,这会导致查询不到匹配的工作项,甚至语法错误。未处理特殊字符风险
如果标题里包含单引号,直接拼字符串会导致WIQL语法错误,推荐使用参数化查询避免这个问题。
修正后的代码:
async function getWorkItemIdByTitle(workItemTitle) { let status = ""; console.log("getting work item ID") console.log(workItemTitle); try { const url = `${orgUrl}/${projectNameForURL}/_apis/wit/wiql?api-version=7.1`; // 使用参数化WIQL查询,避免编码和特殊字符问题 const wiqlQuery = `SELECT [System.Id] FROM WorkItems WHERE [System.Title] = @title`; const response = await axios.post(url, { query: wiqlQuery, parameters: [ { name: "title", value: workItemTitle } ] }, { headers: { 'Content-Type': 'application/json', // 修正Content-Type 'Authorization': `Basic ${Buffer.from(`:${pat}`).toString('base64')}`, }, }); // 使用可选链操作符避免workItems未定义时的报错 if (response.data.workItems?.length > 0) { const workItemId = response.data.workItems[0].id; console.log(`Work item ID for title '${workItemTitle}': ${workItemId}`); status = "Incident Number: " + workItemId; } else { console.log(`No work item found with title '${workItemTitle}'`); status = "No matching incidents found" } } catch (error) { console.error('Error retrieving work item by title:', error.response ? error.response.data : error.message); status = "Error fetching incidents"; } console.log("STATUS: ", status); return status; }
额外提示:
- 确保
orgUrl、projectNameForURL、pat变量已正确赋值,且PAT拥有Work Item Read权限。 - 如果仍有问题,可在catch块中打印完整的
error对象,排查网络或权限相关问题。
内容的提问来源于stack exchange,提问作者Pmd
相关产品推荐
相关产品推荐

