mcpField
S
sentry-javascript-bugs

sentry-javascript-bugs

github.com/getsentry测试与质量45.7k92 次安装今天更新
代码仓库

关于 sentry-javascript-bugs

面向 Sentry 前端代码审查的 JavaScript 缺陷模式技能,依据真实生产问题检查用户指定代码或当前分支差异。它会追踪相关数据流,并仅报告有具体触发路径的中高置信度问题。

主要功能

  1. 01检查空值访问与 API 响应处理
  2. 02审查仪表盘组件和 Trace 视图数据
  3. 03检查 React 生命周期与 AI 数据解析
  4. 04核查数组边界及逻辑正确性
  5. 05提供触发条件与具体代码修复

适用场景

  1. 01审查前端差异中的空值访问风险
  2. 02检查图表和 Trace 视图的异常数据处理
  3. 03排查异步操作与 React 生命周期问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/getsentry/sentry --skill sentry-javascript-bugs

安装后在 Claude Code 中输入/sentry-javascript-bugs确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
references/
ai-insights-parsing.md
api-response-handling.md
dashboard-widget-errors.md
null-reference-errors.md
range-and-bounds-errors.md
react-lifecycle-errors.md
trace-view-errors.md

详细介绍

Sentry JavaScript 前端缺陷模式审查

通过检查那些导致最多真实生产错误的模式,找出 Sentry 前端代码中的缺陷。

本技能编码了来自 428 个真实生产问题的模式(201 个已解决、130 个已忽略、97 个未解决),这些问题在 93,000+ 受影响用户中产生了超过 524,000 个错误事件。这些不是理论风险——它们是实际最常上线的缺陷,并附有来自已解决问题的已知修复方案。

范围

审查用户、Warden 或当前分支 diff 提供的代码。如果用户未提供目标,则审查当前分支 diff。从变更的 hunk 或文件开始,然后仅在需要确认行为时向外读取。

  1. 根据下方的模式检查项分析变更的代码。
  2. 在需要时,使用 Read 和 Grep 追踪初始 diff 之外的数据流。跟踪组件 props、hook 返回值、API 响应结构和状态转换,直到确认行为。
  3. 仅报告 HIGH 和 MEDIUM 置信度的发现。
置信度标准操作
HIGH已追踪代码路径,确认该模式匹配已知缺陷类别报告并附修复方案
MEDIUM存在该模式,但上下文可能减轻其影响报告为需要验证
LOW理论上的或在其他地方已被缓解不报告

步骤 1:对代码进行分类

确定你正在审查的内容并加载相关参考。

代码类型加载参考
Null/undefined 属性访问、可选链、对象解构references/null-reference-errors.md
仪表盘 widget、图表可视化、widget URL 生成references/dashboard-widget-errors.md
Trace 视图、span 详情、trace 树渲染references/trace-view-errors.md
API 调用、响应处理、错误状态、fetch 封装references/api-response-handling.md
React hooks、context provider、渲染循环、组件生命周期references/react-lifecycle-errors.md
AI Insights、大模型提示词解析、gen_ai span 数据references/ai-insights-parsing.md
数组操作、日期/时间值、数字格式化references/range-and-bounds-errors.md

如果代码跨越多个类别,请加载所有相关参考。

步骤 2:检查主要缺陷模式

这些按来自真实生产数据的频率和影响综合排序。

检查 1:Null/Undefined 属性访问——158 个问题,46,337 个事件

代码访问了可能为 null 或 undefined 的值上的属性。这是 Sentry 前端中最常见的单一缺陷模式。

危险信号:

  • 在未进行 null 检查的情况下访问 .id、.slug、.name、.type、.match、.length、.charCodeAt
  • 对来自 API 响应的数据使用 object.property 而非 object?.property
  • 在未进行 null 验证的情况下将 API 响应数据直接传递给工具函数
  • 在未检查元素是否存在的情况下从 querySelector 或 useRef 访问 DOM 元素属性
  • 解构来自可能在加载状态期间返回 null 的 hooks/store 的对象
  • 对已卸载的元素调用 .dispatchEvent()

安全模式:

  • 可选链:obj?.property?.nested
  • 默认值:const value = obj?.field ?? defaultValue
  • 函数调用前的 null 防护:if (data) { parser.parse(data); }
  • 工具函数中对 null/undefined 参数的提前返回
检查 2:仪表盘小组件输入验证 -- 6 个问题,90,482 个事件

小组件可视化组件在接收到非预期格式的数据时会抛出异常。

危险信号:

  • 渲染图表组件时未检查数据是否包含可绘制的值
  • 对不支持多查询的小组件类型调用 getWidgetExploreUrl()
  • 将未定义的 field 值传递给 parseFunction() 或类似的字段解析器
  • 未处理小组件数据获取器中的空 API 响应

安全模式:

  • 渲染前验证数据形状:if (!hasPlottableValues(data)) return <EmptyState />
  • 生成探索 URL 前检查小组件查询数量
  • 守护字段解析器:if (!field) return null
检查 3:Trace 视图数据完整性 -- 12 个问题,328,482 个事件

Trace 树渲染器和 Trace 详情视图会遇到违反结构假设的数据。

危险信号:

  • 构建 Trace 树时未进行环检测(或检测到环但未优雅处理)
  • 从 span 数据中按 ID 查找项目时未检查项目是否可访问
  • 生成 Trace 链接时未验证 traceSlug 非空
  • 在渲染路径中使用 captureException 时未去重(每个渲染周期都会触发)

安全模式:

  • 通过将环节点分离为孤儿根节点来打破环
  • 生成链接前验证 traceSlug:if (!traceSlug) return fallbackLink
  • 使用 ref 对错误捕获去重:if (!capturedRef.current) { captureException(...); capturedRef.current = true; }
  • 渲染 span 详情前检查项目访问权限
检查 4:API 响应形状假设 -- 31 个问题,24,019 个事件

前端代码假设 API 响应具有特定形状,但响应为空、未定义或具有非预期的状态码。

危险信号:

  • 未处理 200 响应体为空的情况(例如 GET /customers/{orgSlug}/ 返回 200 但无响应体)
  • 未处理订阅流程中的 402(Payment Required)状态码
  • 未处理变更端点中的 409(Conflict)状态码
  • 将 UndefinedResponseBodyError 视为非预期错误(它表示 API 未返回可解析的响应体)
  • 假设 SelectAsync 选项始终能成功加载

安全模式:

  • 解析前检查响应体:if (!response.body) return null
  • 在 catch 块中处理特定的 4xx 状态码
  • 为失败的 API 获取提供回退空状态,而不是抛出异常
检查 5:React 生命周期违规 -- 10 个问题,2,595 个事件

组件违反 React 渲染规则,导致无限循环或崩溃。

危险信号:

  • 在 useEffect 中无条件设置状态,且未提供正确的依赖数组
  • 在组织上下文加载之前渲染的组件中调用 useOrganization()
  • 在 Provider 边界之外使用 useContext()
  • 将对象作为 React 子元素传递,而不是字符串/元素
  • 挂载时立即触发重新渲染的组件

安全模式:

  • 始终为 useEffect 提供依赖数组
  • 守护上下文 Hook:const org = useOrganization(); if (!org) return <Loading />
  • 将依赖组织上下文的路由包裹在 Provider 边界中
  • 渲染前验证元素类型:if (typeof Component !== 'function') return null
检查 6:AI 洞察数据解析 -- 2 个问题,3,005 个事件

AI 提示词消息和 gen_ai span 数据的 JSON 解析在非标准格式下失败。

危险信号:

  • 对 ai.prompt.messages span 属性调用 JSON.parse() 时未使用 try-catch
  • 假设所有 AI 模型响应都会产生有效的 JSON
  • 未处理多模态 AI 消息的 “parts” 格式

安全模式:

  • 将所有对外部数据的 JSON.parse 调用包裹在 try-catch 中
  • 解析前检查开头的 [ 或 {
  • 解析失败时提供原始文本回退渲染
检查 7:数组与边界校验 —— 15 个问题,3,120 个事件

数组操作以及数值格式化中使用了超出有效范围的值。

危险信号:

  • 使用 result.push(...largeArray)(数组过大时会崩溃)
  • 向 toLocaleString({maximumFractionDigits: n}) 传入未做钳制的值
  • 从未经验证的时间戳构造 Date 对象
  • 递归渲染组件时没有深度限制

安全模式:

  • 对可能很大的数组使用 concat 或迭代 push
  • 钳制数值格式参数:Math.min(100, Math.max(0, precision))
  • 构造日期前先校验:if (isNaN(new Date(ts).getTime())) return fallback
  • 对深层嵌套结构使用带显式栈的迭代渲染
检查 8:逻辑正确性 —— 不基于模式匹配

在检查完上述所有已知模式后,对改动过的代码本身进行推理:

  • 每条代码路径是否都返回正确的类型(或 JSX)?
  • 条件语句的所有分支是否都处理了(尤其是 switch 中缺失的 else / 默认分支)?
  • 任何 prop 或 state 值(null、undefined、空数组、空字符串)是否会导致意外行为?
  • hook 依赖数组是否正确?缺失依赖会导致闭包过期;多余依赖会导致无限循环。
  • 如果此组件在异步操作中途卸载,是否处理了清理?

只有当你能够追踪到触发该 bug 的具体输入时才报告。不要报告理论上的担忧。

如果所有检查都没有产生潜在发现,就停止并报告零发现。不要为了填充报告而编造问题。当代码中没有匹配这些模式的 bug 时,空结果就是正确的输出。

每个代码位置应只在最具体匹配的模式下报告一次。不要在同一行上以多个检查重复标记。

步骤 3:报告发现

对于每个发现,提供审查框架所需的证据:

  • 精确位置
  • 严重程度与置信度
  • 具体的触发输入或状态
  • 根本原因与后果
  • 如有可用的生产环境先例,提供匹配的先例
  • 具体的代码修复,若框架支持,最好以统一 diff 形式提供

修复建议必须包含实际代码。绝不要建议以注释或 docstring 作为修复。

不要自行规定输出格式 —— 审查框架控制响应结构。

评论

支持 Markdown