Files
JKVideo/docs/superpowers/bug.md
Developer 880e2696da 1
2026-03-11 10:03:46 +08:00

7.5 KiB
Raw Blame History

Bug Report

最后更新2026-03-10


CRITICAL

BUG-01 · video.stat 空指针崩溃

文件: app/video/[bvid].tsx 第 7275、94 行 类型: Logic Bug

VideoItem.stat 在类型定义中为可选字段(stat?: {...}),但代码直接访问 video.stat.view 等属性,无任何空值保护。当 B站 API 返回的视频数据不含 stat 字段时,页面会崩溃。

// 当前(危险)
<StatBadge icon="play" count={video.stat.view} />
评论 {video.stat.reply > 0 ? ...}

// 修复
<StatBadge icon="play" count={video.stat?.view ?? 0} />
评论 {(video.stat?.reply ?? 0) > 0 ? ...}

BUG-02 · 切换视频时评论不重置

文件: hooks/useComments.tsapp/video/[bvid].tsx 第 3133 行 类型: Logic Bug

useComments hook 内部没有重置机制。当用户从视频 Aaid=123已加载 3 页)跳转到视频 Baid=456

  • comments 数组仍含视频 A 的内容
  • page 仍为 4视频 B 的评论从第 4 页开始请求
  • 结果:视频 A 和视频 B 的评论混在一起显示

useComments 缺少一个 reset() 方法,[bvid].tsx 也没有在 bvid 变化时调用清理。

// hooks/useComments.ts 需要增加
const reset = useCallback(() => {
  setComments([]);
  setPage(1);
  setHasMore(true);
}, []);

// app/video/[bvid].tsx 需要在 bvid 变化时调用
useEffect(() => {
  clearVideo();
  resetComments(); // 缺失
}, [bvid]);

BUG-03 · useComments 跨视频 page 状态污染

文件: hooks/useComments.ts 第 24 行 类型: Race Condition

load 回调将 pageloadinghasMore 列入 useCallback 依赖数组。当 aid 变化(切换视频)时,page 仍是上一个视频的值,新 load 调用会从错误的页码请求评论。与 BUG-02 同根,但原因不同:即使父组件调用 reset,旧 load 闭包内的 page 可能仍是旧值。

// 当前
}, [aid, page, loading, hasMore]); // page 污染导致跨视频分页错误

// 修复:用 ref 追踪 page不纳入依赖
const pageRef = useRef(1);
const load = useCallback(async () => {
  ...
  const data = await getComments(aid, pageRef.current);
  pageRef.current += 1;
}, [aid]); // 只依赖 aid

MAJOR

BUG-04 · 视频加载失败无任何用户反馈

文件: app/video/[bvid].tsx 第 22 行 类型: UX

useVideoDetail 返回 error 字段,但 [bvid].tsx 完全忽略它。网络错误、API 403、视频下架等场景下用户看到的是永久的 loading 动画或空白页,无法知晓发生了什么。

// 当前error 被解构但从未使用)
const { video, playData, loading: videoLoading, qualities, currentQn, changeQuality } = useVideoDetail(bvid);

// 修复:增加 error 处理
const { video, playData, loading: videoLoading, error, qualities, currentQn, changeQuality } = useVideoDetail(bvid);
// 在 ScrollView 内渲染
{error && <Text style={styles.errorTxt}>加载失败:{error}</Text>}

BUG-05 · Promise.all 导致热力图和缩略图互相阻断

文件: components/NativeVideoPlayer.tsxheatmap useEffect 类型: Error Handling

热力图(getHeatmap)和视频截图(getVideoShot)使用 Promise.all 并行请求。任意一个失败,另一个的结果也会被丢弃。对于没有热力图的视频,缩略图也无法加载。

// 当前
Promise.all([getHeatmap(bvid), getVideoShot(bvid, cid)]).then(...)

// 修复:独立处理各自失败
Promise.allSettled([getHeatmap(bvid), getVideoShot(bvid, cid)]).then(([heatRes, shotRes]) => {
  if (heatRes.status === 'fulfilled' && heatRes.value?.pb_data) { ... }
  if (shotRes.status === 'fulfilled' && shotRes.value?.image?.length) { ... }
});

BUG-06 · LoginModal pollQRCode 无错误处理

文件: components/LoginModal.tsxsetInterval 回调) 类型: Error Handling

setInterval 内的 await pollQRCode(qrKey) 若抛出异常(网络断开、超时等),错误被静默丢弃,定时器继续运行。用户看到的是二维码一直停在"等待扫码"状态,没有任何提示。

// 修复:增加 try-catch
pollRef.current = setInterval(async () => {
  try {
    const result = await pollQRCode(qrKey);
    ...
  } catch {
    // 网络异常时更新状态提示用户
    setStatus('error');
  }
}, 2000);

BUG-07 · utils/buildMpd.ts 死代码

文件: utils/buildMpd.ts 类型: Code Quality

该文件定义了 buildMpd() 函数,但全项目无任何 import。实际 MPD 构建逻辑在 utils/dash.ts 中实现。buildMpd.ts 中的 SegmentBase 使用硬编码的 range="0-999" 而非真实的 byte range直接使用会导致 ExoPlayer 播放失败。应删除该文件。


MINOR

BUG-08 · expo-file-system/legacy 废弃导入

文件: utils/dash.ts 第 1 行 类型: Deprecation

import * as FileSystem from 'expo-file-system/legacy'; // 废弃路径

新版 expo-file-system 将 legacy API 移至子路径是临时过渡方案,后续版本可能移除。需跟进 expo-file-system 更新,迁移至正式 API。


BUG-09 · 进度条 measureInWindow 异步竞态

文件: components/NativeVideoPlayer.tsxmeasureTrack 类型: Race Condition

控制层从隐藏变为显示时,trackWrapper 重新挂载,onLayout 触发 measureInWindow(异步)。若用户在 measureInWindow 回调返回前立即拖动进度条,barOffsetX.current 为旧值0 或上次值),导致 touchX 计算偏差,缩略图位置和 seek 位置偏移。


BUG-10 · "加载更多评论"按钮在首次加载前不可见

文件: app/video/[bvid].tsx 第 108112 行 类型: UX

按钮渲染条件为 !cmtLoading && comments.length > 0。首次进入视频详情时,评论需要用户手动点击"加载更多"触发,但在 loadCommentsuseEffect 自动调用(第 32 行)完成前,按钮不存在。若自动加载失败,用户无法重试。


BUG-11 · useVideoDetail 登录态变化时不重置 loading

文件: hooks/useVideoDetail.ts 第 5357 行 类型: UX

登录/登出时触发 fetchPlayData 重新拉取清晰度,但未设置 loading = true。用户看不到加载状态变化,若请求耗时较长,可能出现短暂的旧清晰度视频在播放的情况。


汇总

ID 文件 严重度 类型 一句话描述
BUG-01 app/video/[bvid].tsx CRITICAL Logic Bug video.stat 无空值保护,可能崩溃
BUG-02 hooks/useComments.ts CRITICAL Logic Bug 切换视频时评论状态不清空
BUG-03 hooks/useComments.ts CRITICAL Race Condition page 状态跨视频污染
BUG-04 app/video/[bvid].tsx MAJOR UX 视频加载失败无任何用户反馈
BUG-05 components/NativeVideoPlayer.tsx MAJOR Error Handling Promise.all 导致热力图/缩略图互相阻断
BUG-06 components/LoginModal.tsx MAJOR Error Handling 二维码轮询网络异常被静默吞掉
BUG-07 utils/buildMpd.ts MAJOR Code Quality 死代码,硬编码错误 byte range
BUG-08 utils/dash.ts MINOR Deprecation expo-file-system/legacy 废弃导入
BUG-09 components/NativeVideoPlayer.tsx MINOR Race Condition 进度条测量异步竞态导致拖动偏差
BUG-10 app/video/[bvid].tsx MINOR UX 首次加载失败无重试入口
BUG-11 hooks/useVideoDetail.ts MINOR UX 登录态变化时不显示重新加载状态