Skip to main content
Glama
handlers.ts5.73 kB
import { findCodeOwner, getPullRequestByCommit, createJiraTicket } from "./api.js"; import type { ErrorInvestigationResult, ErrorAnalysisData } from "./types.js"; /** * Investigate error - find code owner and related PRs * This returns data for AI analysis before creating JIRA ticket */ export async function investigateError( filePath: string, lineNumber: number, branch: string = "release/1.5" ): Promise<ErrorInvestigationResult> { // Step 1: Find code owner const owner = await findCodeOwner(filePath, lineNumber, branch); // Step 2: Get PR info (filter by owner and MERGED status) const prInfo = await getPullRequestByCommit(owner.commitId, owner.name, "MERGED"); // Step 3: Extract PR links const relatedPRLinks = prInfo.values.map(pr => pr.links.self[0].href); return { codeOwner: owner, pullRequests: prInfo, relatedPRLinks, filePath, lineNumber, branch, }; } /** * Format JIRA description with error info and investigation results */ export function formatJiraDescription( errorAnalysis: string | ErrorAnalysisData, investigation: ErrorInvestigationResult ): string { const { codeOwner, pullRequests, filePath, lineNumber, branch } = investigation; // 解析或使用 errorAnalysis(包含错误信息、报错分析、修改建议) let errorData: ErrorAnalysisData; if (typeof errorAnalysis === 'string') { // 如果是字符串,尝试解析 JSON try { errorData = JSON.parse(errorAnalysis); } catch { // 如果不是 JSON,当作普通错误信息处理 errorData = { errorInfo: errorAnalysis, analysis: "未使用大模型分析", suggestions: "未使用大模型分析" }; } } else { // 如果已经是对象,直接使用 errorData = errorAnalysis; } // 格式化错误信息部分 let description = "h2. 错误信息\r\n{code:java}\r\n" + (errorData.errorInfo || errorAnalysis) + "\r\n{code}\r\n\r\n"; description += "h2. 报错分析\r\n" + (errorData.analysis || "未使用大模型分析") + "\r\n\r\n"; description += "h2. 修改建议\r\n" + (errorData.suggestions || "未使用大模型分析") + "\r\n\r\n"; description += "----\r\n\r\n"; description += "h2. 代码位置\r\n"; description += "* 文件: {{" + filePath + "}}\r\n"; description += "* 行号: {{" + lineNumber + "}}\r\n"; description += "* 分支: {{" + branch + "}}\r\n\r\n"; description += "h2. 代码责任人\r\n"; description += "* 作者: " + codeOwner.author + "\r\n"; description += "* 邮箱: " + codeOwner.email + "\r\n"; description += "* Commit: {{" + codeOwner.commitId + "}}\r\n"; description += "* [查看Commit|" + process.env.BITBUCKET_BASE_URL + "/projects/" + process.env.BITBUCKET_PROJECT?.toUpperCase() + "/repos/" + process.env.BITBUCKET_REPO + "/commits/" + codeOwner.commitId + "]\r\n\r\n"; // PR 信息已经在 investigateError 中过滤过了(只包含责任人的 MERGED PR) if (pullRequests.values.length > 0) { description += "h2. 相关 Pull Request\r\n"; pullRequests.values.forEach(pr => { description += "* PR #" + pr.id + " - " + pr.state + "\r\n"; description += "** 标题: " + pr.title + "\r\n"; description += "** 作者: " + pr.author.user.displayName + "\r\n"; description += "** [查看详情|" + pr.links.self[0].href + "]\r\n"; }); } return description; } /** * Create JIRA ticket with investigation data */ export async function createJiraTicketWithInvestigation( summary: string, investigationData: string | ErrorInvestigationResult, assignee: string, errorAnalysis: string | ErrorAnalysisData, labels: string[] = [] ) { // 解析或验证 investigationData let investigation: ErrorInvestigationResult; if (typeof investigationData === 'string') { // 如果是字符串,尝试解析 JSON try { investigation = JSON.parse(investigationData); } catch (error) { throw new Error( `无效的 investigationData 格式:无法解析 JSON 字符串。` + `请确保传入的是 investigate_error 工具返回的完整、未经修改的 JSON 字符串,` + `解决方法:\n` + `1. 检查之前是否已调用 investigate_error,如果有,请使用其返回的完整结果(JSON 字符串或对象)\n` + `2. 如果之前的结果丢失或不完整,请重新调用 investigate_error 工具获取最新数据\n` + `3. 不要手动构造 investigationData,必须使用 investigate_error 的原始返回值` ); } } else { // 如果已经是对象,直接使用 investigation = investigationData; } // 验证数据结构完整性 const missingFields = []; if (!investigation.codeOwner) missingFields.push('codeOwner'); if (!investigation.pullRequests) missingFields.push('pullRequests'); if (missingFields.length > 0) { throw new Error( `无效的调查数据结构:缺少 ${missingFields.join('、')} 字段。` + `investigationData 必须是 investigate_error 工具返回的完整数据。\n` + `解决方法:\n` + `1. 检查之前是否已调用 investigate_error,如果有,请使用其返回的完整结果(JSON 字符串或对象)\n` + `2. 如果之前的结果丢失或不完整,请重新调用 investigate_error 工具获取最新数据\n` + `3. 不要手动构造 investigationData,必须使用 investigate_error 的原始返回值` ); } // 使用解析后的对象和 errorAnalysis 格式化 JIRA 描述 const finalDescription = formatJiraDescription(errorAnalysis, investigation); // 创建 JIRA ticket return createJiraTicket(summary, finalDescription, assignee, labels); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wycCome/mcp-error-tracing'

If you have feedback or need assistance with the MCP directory API, please join our Discord server