跳转到主要内容
本页属于设计哲学指南,该页索引全部主题。部署拓扑、目录结构与 CI/CD 请参阅 ARCHITECTURE.md。

错误追踪

Sentry 错误噪声过滤

Sentry SDK 初始化包含 beforeSend 钩子和 ignoreErrors 列表,抑制已知的不可操作错误来源 — 完全发生在无 source-map 帧的压缩代码中的 Three.js WebGL 遍历崩溃、来自浏览器扩展的跨域 Web Worker 构建失败、iOS 媒体元素崩溃,以及扩展注入的 jQuery $。Three.js 过滤器特别避免一刀切抑制:仅丢弃所有栈帧都是匿名或来自压缩 bundle 的事件。如果哪怕有一帧具有 source-map 的 .ts 文件名,该事件将被保留以供调查。

错误追踪与生产强化

Sentry 在生产环境中捕获未处理异常和 Promise 拒绝,具备环境感知路由(生产环境在 worldmonitor.app,预览环境在 *.vercel.app,localhost 和 Tauri 桌面端禁用)。 配置包含 30+ 个 ignoreErrors 模式,抑制以下噪声:
  • 第三方 WebView 注入 — Twitter、Facebook 和 Instagram 内嵌浏览器注入引用未定义变量(CONFIG、currentInset)的脚本
  • 浏览器扩展 — 失败 importScripts 或违反 CSP 策略的 Chrome/Firefox 扩展
  • WebGL 上下文丢失 — MapLibre/deck.gl 中可自恢复的瞬时 GPU 崩溃
  • iOS Safari 怪癖 — 后台标签页被杀导致的 IndexedDB 连接断开、自动播放策略导致的 NotAllowedError
  • 网络瞬时问题 — TypeError: Failed to fetch、TypeError: Load failed、TypeError: cancelled
  • MapLibre 内部崩溃 — 源自地图分块的 style layers、light 和 placement 中的空访问
自定义 beforeSend 钩子提供第二阶段过滤:抑制单字符错误消息(压缩产物)、来自浏览器扩展的 Importing a module script failed 错误(通过栈跟踪中的 chrome-extension: 或 moz-extension: 识别),以及栈跟踪源自地图分块文件时的 MapLibre 内部空访问崩溃。 分块重载守卫 — 部署后,持有过期浏览器标签页的用户在动态导入的分块具有新内容哈希文件名时可能遇到 vite:preloadError 事件。守卫监听此事件,每个构建最多重载一次页面,并将已用掉的重载记录在 sessionStorage 中(sessionStorage 不可用时改用 localStorage)。应用成功启动后不会清除该记录,因此每次加载都失败的分块(例如被广告拦截器屏蔽的分块)只会造成一次重载,而不是循环重载。没有任何存储能保存该记录时,守卫完全不重载。延迟加载的 Sentry 加载器通过 preventDefault() 认领其自身分块的失败,因此被屏蔽的 Sentry 分块永远不会触发页面重载。跨越后续部署仍保持打开的标签页由过期构建检查处理。 存储配额管理 — 当设备的 localStorage 或 IndexedDB 配额耗尽时(移动版 Safari 5MB 限制常见),全局 _storageQuotaExceeded 标志禁用持久缓存(IndexedDB + localStorage 回退)和工具 saveToStorage() 函数的所有后续写入尝试。该标志在首次 name === 'QuotaExceededError' 或 code === 22 的 DOMException 时设置,防止重复失败写入导致的级联错误。读取操作继续正常 — 缓存数据仍可访问,仅新写入被抑制。 事务以 10% 采样以在可观测性与成本间平衡。发布追踪(worldmonitor@{version})支持跨部署的回归检测。

容错

外部 API 不可靠。速率限制、中断和网络错误不可避免。系统实现熔断器模式以维持可用性。

熔断器模式

每个外部服务都包装在追踪失败的熔断器中:
冷却期间行为:
  • 新请求返回缓存数据(如可用)
  • UI 显示”暂时不可用”状态
  • 不进行 API 调用(防止轰炸)

受保护服务

RSS 订阅源使用每源独立熔断器 — 一个失败订阅源不影响其他。

优雅降级

当服务进入冷却时:
  1. 缓存数据继续显示(过期但可用)
  2. 状态面板显示服务健康度
  3. 冷却到期时自动恢复
  4. 无需用户干预

系统健康监控

状态面板(通过标题栏健康指示器访问)提供数据源状态和系统健康度的实时可见性。

健康指示器

标题栏显示系统健康徽章: 点击指示器展开完整状态面板。

数据源状态

状态面板列出所有数据订阅源及其当前状态:

每订阅源信息

每条订阅源显示:
  • 来源名称 - 数据提供商
  • 上次更新 - 距上次成功抓取的时间
  • 下次刷新 - 距下次计划抓取的倒计时
  • 冷却剩余 - 距熔断器重置的时间(如处于冷却)

为何重要

外部 API 不可靠。状态面板帮助你了解:
  • 数据新鲜度 - 新闻订阅源是最新的还是过期的?
  • 覆盖缺口 - 哪些来源当前不可用?
  • 恢复时间线 - 失败来源何时重试?
这种透明性使你能知情解读仪表盘数据。

数据新鲜度追踪

除简单的”在线/离线”状态外,系统为每个数据源追踪细粒度新鲜度,以指示数据可靠性和陈旧度。

新鲜度等级

来源专属阈值

每个数据源有校准的新鲜度预期:

视觉指示器

状态面板为每个来源显示新鲜度:
  • 彩色点 指示新鲜度等级
  • 距更新时间 显示确切陈旧度
  • 下次刷新倒计时 显示数据何时更新

为何重要

理解数据新鲜度对决策至关重要:
  • “新鲜”的地震订阅源意味着显示了近期事件
  • “过期”的新闻订阅源意味着你可能错过突发报道
  • “关键”的 AIS 流意味着船舶位置不可靠
这种可见性使你在解读仪表盘时能适当校准置信度。

核心 vs. 可选来源

数据源按其对风险评估的重要性分类: 战略风险概览面板根据核心来源可用性调整其显示:

新鲜度感知风险评估

复合风险评分根据数据新鲜度调整:
这防止了系统实际缺乏数据做出判断时发出虚假”全部安全”信号。

服务状态监控

服务状态面板追踪 WorldMonitor 用户可能依赖的外部服务的运行健康度。

受监控服务

状态等级

为何重要

外部服务中断可能影响:
  • AI 摘要(OpenRouter 中断)
  • 部署管道(Vercel、GitHub 中断)
  • API 可用性(Cloudflare、AWS 中断)
监控这些服务在仪表盘功能异常时提供上下文。