sentry-javascript-bugs
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSentry JavaScript Frontend Bug Pattern Review
Sentry JavaScript前端Bug模式审查
Find bugs in Sentry frontend code by checking for the patterns that cause real production errors.
This skill encodes patterns from 428 real production issues (201 resolved, 130 ignored, 97 unresolved) generating over 524,000 error events across 93,000+ affected users. These are not theoretical risks -- they are the actual bugs that ship most often, with known fixes from resolved issues.
通过检查引发真实生产错误的模式,查找Sentry前端代码中的Bug。
该技能编码了来自428个真实生产问题(201个已解决、130个已忽略、97个未解决)的模式,这些问题在93000+受影响用户中产生了超过524000个错误事件。这些不是理论风险——它们是最常出现的实际Bug,并且有来自已解决问题的已知修复方案。
Scope
审查范围
You receive scoped code chunks from Warden's diff pipeline. Each chunk is a changed hunk (or coalesced group of nearby hunks) with surrounding context.
- Analyze the chunk against the pattern checks below.
- Use and
Readto trace data flow beyond the chunk when needed — follow component props, hook return values, API response shapes.Grep - Report only HIGH and MEDIUM confidence findings.
| Confidence | Criteria | Action |
|---|---|---|
| HIGH | Traced the code path, confirmed the pattern matches a known bug class | Report with fix |
| MEDIUM | Pattern is present but context may mitigate it | Report as needs verification |
| LOW | Theoretical or mitigated elsewhere | Do not report |
你会收到来自Warden差异流水线的限定范围代码块。每个代码块是一个已更改的代码段(或合并后的邻近代码段组),并带有上下文信息。
- 对照下方的模式检查规则分析代码块。
- 必要时使用和
Read追踪代码块之外的数据流——追踪组件props、Hook返回值、API响应结构。Grep - 仅报告高和中置信度的发现。
| 置信度 | 判断标准 | 处理方式 |
|---|---|---|
| 高 | 追踪了代码路径,确认模式匹配已知Bug类别 | 附带修复方案进行报告 |
| 中 | 存在匹配模式,但上下文可能缓解风险 | 报告为需要验证的问题 |
| 低 | 仅为理论风险或已在其他地方得到缓解 | 不进行报告 |
Step 1: Classify the Code
步骤1:代码分类
Determine what you are reviewing and load the relevant reference.
| Code Type | Load Reference |
|---|---|
| Null/undefined property access, optional chaining, object destructuring | |
| Dashboard widgets, chart visualization, widget URL generation | |
| Trace views, span details, trace tree rendering | |
| API calls, response handling, error states, fetch wrappers | |
| React hooks, context providers, render loops, component lifecycle | |
| AI Insights, LLM prompt parsing, gen_ai span data | |
| Array operations, date/time values, numeric formatting | |
If the code spans multiple categories, load all relevant references.
确定你要审查的代码类型,并加载相关参考文档。
| 代码类型 | 加载参考文档 |
|---|---|
| 空值/未定义属性访问、可选链、对象解构 | |
| 仪表板组件、图表可视化、组件URL生成 | |
| 追踪视图、Span详情、追踪树渲染 | |
| API调用、响应处理、错误状态、Fetch封装 | |
| React Hooks、上下文提供者、渲染循环、组件生命周期 | |
| AI洞察、LLM提示解析、gen_ai Span数据 | |
| 数组操作、日期/时间值、数值格式化 | |
如果代码涉及多个类别,请加载所有相关参考文档。
Step 2: Check for Top Bug Patterns
步骤2:检查常见Bug模式
These are ordered by combined frequency and impact from real production data.
以下是根据真实生产数据的出现频率和影响程度排序的Bug模式。
Check 1: Null/Undefined Property Access -- 158 issues, 46,337 events
检查1:空值/未定义属性访问 -- 158个问题,46337个错误事件
Code accesses a property on a value that may be null or undefined. This is the single most common bug pattern in the Sentry frontend.
Red flags:
- Accessing ,
.id,.slug,.name,.type,.match,.lengthwithout null checks.charCodeAt - Using instead of
object.propertyon data from API responsesobject?.property - Passing API response data directly to utility functions without null validation
- Accessing DOM element properties from or
querySelectorwithout checking if the element existsuseRef - Destructuring objects from hooks/stores that may return null during loading states
- Calling on elements that have been unmounted
.dispatchEvent()
Safe patterns:
- Optional chaining:
obj?.property?.nested - Default values:
const value = obj?.field ?? defaultValue - Null guards before function calls:
if (data) { parser.parse(data); } - Early returns for null/undefined parameters in utility functions
代码访问了可能为空或未定义的值的属性。这是Sentry前端中最常见的Bug模式。
危险信号:
- 未做空值检查就访问、
.id、.slug、.name、.type、.match、.length.charCodeAt - 对来自API响应的数据使用而非
object.propertyobject?.property - 未做空值验证就将API响应数据直接传入工具函数
- 未检查元素是否存在,就访问来自或
querySelector的DOM元素属性useRef - 对Hook/Store返回的可能为空的对象进行解构,而此时组件正处于加载状态
- 对已卸载的元素调用
.dispatchEvent()
安全实践:
- 使用可选链:
obj?.property?.nested - 设置默认值:
const value = obj?.field ?? defaultValue - 函数调用前做空值判断:
if (data) { parser.parse(data); } - 在工具函数中对空值/未定义参数提前返回
Check 2: Dashboard Widget Input Validation -- 6 issues, 90,482 events
检查2:仪表板组件输入验证 -- 6个问题,90482个错误事件
Widget visualization components throw when receiving data in unexpected formats.
Red flags:
- Rendering chart components without checking if data contains plottable values
- Calling for widget types that do not support multiple queries
getWidgetExploreUrl() - Passing undefined values to
fieldor similar field parsersparseFunction() - Not handling empty API responses in widget data fetchers
Safe patterns:
- Validate data shape before rendering:
if (!hasPlottableValues(data)) return <EmptyState /> - Check widget query count before generating explore URLs
- Guard field parsers:
if (!field) return null
仪表板可视化组件在收到意外格式的数据时会抛出错误。
危险信号:
- 未检查数据是否包含可绘制值就渲染图表组件
- 为不支持多查询的组件类型调用
getWidgetExploreUrl() - 将未定义的值传入
field或类似的字段解析器parseFunction() - 未在组件数据获取器中处理空API响应
安全实践:
- 渲染前验证数据结构:
if (!hasPlottableValues(data)) return <EmptyState /> - 生成探索URL前检查组件查询数量
- 为字段解析器添加防护:
if (!field) return null
Check 3: Trace View Data Integrity -- 12 issues, 328,482 events
检查3:追踪视图数据完整性 -- 12个问题,328482个错误事件
The trace tree renderer and trace detail views encounter data that violates structural assumptions.
Red flags:
- Building trace trees without cycle detection (or detecting cycles but not handling them gracefully)
- Looking up projects by ID from span data without checking if the project is accessible
- Generating trace links without validating is non-empty
traceSlug - Using in render paths without deduplication (fires every render cycle)
captureException
Safe patterns:
- Break cycles by detaching cyclic nodes as orphan roots
- Validate traceSlug before generating links:
if (!traceSlug) return fallbackLink - Deduplicate error captures using a ref:
if (!capturedRef.current) { captureException(...); capturedRef.current = true; } - Check project access before rendering span details
追踪树渲染器和追踪详情视图遇到了违反结构假设的数据。
危险信号:
- 构建追踪树时未检测循环(或检测到循环但未优雅处理)
- 根据Span数据中的项目ID查找项目,但未检查该项目是否可访问
- 生成追踪链接时未验证非空
traceSlug - 在渲染路径中使用但未做去重处理(每次渲染都会触发)
captureException
安全实践:
- 通过将循环节点分离为独立根节点来打破循环
- 生成链接前验证traceSlug:
if (!traceSlug) return fallbackLink - 使用ref进行错误捕获去重:
if (!capturedRef.current) { captureException(...); capturedRef.current = true; } - 渲染Span详情前检查项目访问权限
Check 4: API Response Shape Assumptions -- 31 issues, 24,019 events
检查4:API响应结构假设 -- 31个问题,24019个错误事件
Frontend code assumes API responses have a specific shape but the response is empty, undefined, or has an unexpected status code.
Red flags:
- Not handling 200 responses with empty bodies (e.g., returns 200 with no body)
GET /customers/{orgSlug}/ - Not handling 402 (Payment Required) status codes in subscription flows
- Not handling 409 (Conflict) status codes in mutation endpoints
- Treating as unexpected (it indicates the API returned no parseable body)
UndefinedResponseBodyError - Assuming SelectAsync options will always load successfully
Safe patterns:
- Check response body before parsing:
if (!response.body) return null - Handle specific 4xx status codes in catch blocks
- Provide fallback empty states for failed API fetches instead of throwing
前端代码假设API响应具有特定结构,但实际响应为空、未定义或状态码不符合预期。
危险信号:
- 未处理返回空响应体的200状态码(例如返回200但无响应体)
GET /customers/{orgSlug}/ - 未在订阅流程中处理402(支付要求)状态码
- 未在突变端点中处理409(冲突)状态码
- 将视为意外错误(该错误表示API未返回可解析的响应体)
UndefinedResponseBodyError - 假设SelectAsync选项总能加载成功
安全实践:
- 解析前检查响应体:
if (!response.body) return null - 在catch块中处理特定的4xx状态码
- API请求失败时提供备用空状态,而非抛出错误
Check 5: React Lifecycle Violations -- 10 issues, 2,595 events
检查5:React生命周期规则违反 -- 10个问题,2595个错误事件
Components violate React rendering rules, causing infinite loops or crashes.
Red flags:
- Setting state unconditionally in without proper dependency arrays
useEffect - Calling in components that render before organization context is loaded
useOrganization() - Using outside the provider boundary
useContext() - Passing objects as React children instead of strings/elements
- Components that trigger immediate re-render on mount
Safe patterns:
- Always provide dependency arrays for
useEffect - Guard context hooks:
const org = useOrganization(); if (!org) return <Loading /> - Wrap organization-dependent routes in a provider boundary
- Validate element types before rendering:
if (typeof Component !== 'function') return null
组件违反了React渲染规则,导致无限循环或崩溃。
危险信号:
- 在中无条件设置状态,且未提供正确的依赖数组
useEffect - 在组织上下文加载完成前,就在组件中调用
useOrganization() - 在Provider边界之外使用
useContext() - 将对象作为React子元素传递,而非字符串/元素
- 组件挂载后立即触发重新渲染
安全实践:
- 始终为提供依赖数组
useEffect - 为上下文Hook添加防护:
const org = useOrganization(); if (!org) return <Loading /> - 将依赖组织信息的路由包裹在Provider边界内
- 渲染前验证元素类型:
if (typeof Component !== 'function') return null
Check 6: AI Insights Data Parsing -- 2 issues, 3,005 events
检查6:AI洞察数据解析 -- 2个问题,3005个错误事件
JSON parsing of AI prompt messages and gen_ai span data fails on non-standard formats.
Red flags:
- Calling on
JSON.parse()span attributes without try-catchai.prompt.messages - Assuming all AI model responses produce valid JSON
- Not handling the "parts" format for multi-modal AI messages
Safe patterns:
- Wrap all calls on external data in try-catch
JSON.parse - Check for leading or
[before parsing{ - Provide raw-text fallback rendering when parsing fails
对AI提示消息和gen_ai Span数据的JSON解析因非标准格式而失败。
危险信号:
- 未使用try-catch包裹对Span属性的
ai.prompt.messages调用JSON.parse() - 假设所有AI模型响应都能生成有效的JSON
- 未处理多模态AI消息的“parts”格式
安全实践:
- 对所有外部数据的调用都用try-catch包裹
JSON.parse - 解析前检查是否以或
[开头{ - 解析失败时提供原始文本回退渲染
Check 7: Array and Bounds Validation -- 15 issues, 3,120 events
检查7:数组与边界验证 -- 15个问题,3120个错误事件
Array operations and numeric formatting with values that exceed valid ranges.
Red flags:
- Using (crashes when array is too large)
result.push(...largeArray) - Passing unclamped values to
toLocaleString({maximumFractionDigits: n}) - Constructing Date objects from unvalidated timestamps
- Recursive component rendering without depth limits
Safe patterns:
- Use or iterative push for potentially large arrays
concat - Clamp numeric format parameters:
Math.min(100, Math.max(0, precision)) - Validate dates before constructing:
if (isNaN(new Date(ts).getTime())) return fallback - Use iterative rendering with explicit stacks for deeply nested structures
数组操作和数值格式化使用了超出有效范围的值。
危险信号:
- 使用(数组过大时会崩溃)
result.push(...largeArray) - 将未限制范围的值传入
toLocaleString({maximumFractionDigits: n}) - 使用未验证的时间戳构造Date对象
- 无深度限制的递归组件渲染
安全实践:
- 对可能过大的数组使用或迭代式push
concat - 限制数值格式化参数范围:
Math.min(100, Math.max(0, precision)) - 构造前验证日期有效性:
if (isNaN(new Date(ts).getTime())) return fallback - 对深度嵌套结构使用带显式栈的迭代式渲染
Check 8: Logic Correctness -- not pattern-based
检查8:逻辑正确性 -- 非模式类检查
After checking all known patterns above, reason about the changed code itself:
- Does every code path return the correct type (or JSX)?
- Are all branches of conditionals handled (especially missing / default cases in switches)?
else - Can any prop or state value (null, undefined, empty array, empty string) cause unexpected behavior?
- Are hook dependency arrays correct? Missing deps cause stale closures; extra deps cause infinite loops.
- If this component unmounts mid-async-operation, is cleanup handled?
Only report if you can trace a specific input that triggers the bug. Do not report theoretical concerns.
If no checks produced a potential finding, stop and report zero findings. Do not invent issues to fill the report. An empty result is the correct output when the code has no bugs matching these patterns.
Each code location should be reported once under the most specific matching pattern. Do not flag the same line under multiple checks.
完成上述所有已知模式检查后,分析代码本身的逻辑:
- 所有代码路径是否都返回了正确的类型(或JSX)?
- 条件语句的所有分支是否都已处理(尤其是switch语句中缺失的/default分支)?
else - 任何prop或state值(空值、未定义、空数组、空字符串)是否会导致意外行为?
- Hook的依赖数组是否正确?缺失依赖会导致闭包过时;多余依赖会导致无限循环。
- 如果组件在异步操作中途卸载,是否已处理清理逻辑?
仅当你能追踪到触发Bug的特定输入时才进行报告。不要报告理论上的风险。
如果所有检查都未发现潜在问题,请停止并报告无发现。不要为了填充报告而编造问题。当代码中没有匹配这些模式的Bug时,空结果就是正确的输出。
每个代码位置应在最匹配的特定模式下仅报告一次。不要在多个检查中标记同一行代码。
Step 3: Report Findings
步骤3:报告发现
For each finding, include:
- Title: Short description of the bug
- Severity: high, medium, or low
- Location: File path and line number
- Description: Root cause → consequences (2-4 sentences)
- Precedent: A real production issue ID (e.g., "Similar to JAVASCRIPT-2NQW: null charCodeAt in SQL parser, 39K events")
- Fix: A unified diff showing the code fix
Fix suggestions must include actual code. Never suggest a comment or docstring as a fix.
Do not prescribe your own output format — the review harness controls the response structure.
每个发现需包含以下内容:
- 标题:Bug的简短描述
- 严重程度:高、中或低
- 位置:文件路径和行号
- 描述:根本原因 → 影响(2-4句话)
- 参考案例:真实生产问题ID(例如:"类似JAVASCRIPT-2NQW:SQL解析器中的空值charCodeAt调用,39000个错误事件")
- 修复方案:展示代码修复的统一差异对比
修复建议必须包含实际代码。切勿建议使用注释或文档字符串作为修复方案。
不要自行定义输出格式——审查工具会控制响应结构。",