uni.getStorageSync('user') 在 key 从未写过的 UniApp 平台下默认返回 ""(空串)
而非 null/undefined,旧式 `JSON.parse(uni.getStorageSync('user')) || {}` 在
parse 阶段直接抛 `SyntaxError: Unexpected end of JSON input`,导致 quickLogin
setup 崩溃,并触发 Vue 二次告警 `Invalid vnode type: undefined`。
新增 utils/getStoredUser.js 单点封装,统一处理:
- 空值/损坏 JSON 兜底(返回 null,不抛)
- 与 store/modules/user.js 初始化块同源守卫
- 失败 warn 级别日志,不影响业务
替换全库 16 处不安全 `JSON.parse(userStr)` 调用:
composables/useLaserMint.js composables/useShare.js
utils/guideConfig.js utils/preloadApi/core.js
pages/castlove/lenticular/lenticular-result.vue
pages/support-activity/index.vue pages/support-activity/components/{TopRanking,ActionBar}.vue
pages/components/{Header,ShareModal,ShareReportButtons}.vue
pages/tasks/{GuideModal,daily-tasks}.vue
pages/asset-detail/asset-detail.vue pages/exhibition/exhibition.vue
pages/profile/profile.vue pages/login/quickLogin.vue(原崩点)
净 -18 行,17 文件改动 + 1 文件新增。后续如需支持多 key(如 'adminUser'),
把 getStoredUser 扩成泛型 getStoredJSON(key) 即可。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
44 lines
2.1 KiB
JavaScript
44 lines
2.1 KiB
JavaScript
// frontend/utils/getStoredUser.js
|
|
// 安全读取 uni.getStorageSync('user') 并 JSON.parse —— 单点封装,消除全库 ~20 处
|
|
// 重复且不安全的 `JSON.parse(userStr)` 裸调用。
|
|
//
|
|
// 已知坑(踩过 2 次,均以红色 stack trace 形式出现):
|
|
// 1. `uni.getStorageSync('user')` 在 key 从未写过的 UniApp 平台下默认返回 ""
|
|
// (空串)而不是 null/undefined,旧式 `JSON.parse(getStorageSync('user')) || {}`
|
|
// 会在 parse 阶段直接抛 `SyntaxError: Unexpected end of JSON input`,setup 崩溃 →
|
|
// Vue 触发 `[Vue warn]: Invalid vnode type when creating vnode: undefined`
|
|
// 二次告警(同一个根因)。最低成本修复是 `|| '{}'` 兜底,但仍无法防 JSON 损坏场景。
|
|
// 2. 上线后曾遇到"token 有效但 user 缓存被清"的中间态
|
|
// (升级包 / 跨设备 tab 登出 / 部分页面单独清缓存),彼时 setup 抛错导致整页白屏。
|
|
//
|
|
// 使用规范:
|
|
// import { getStoredUser } from '@/utils/getStoredUser'
|
|
// const user = getStoredUser() // 失败返回 null
|
|
// const user = getStoredUser() || {} // 失败降级为空对象
|
|
// const uid = getStoredUser()?.uid // 失败时为 undefined
|
|
//
|
|
// 与 store/modules/user.js 初始化块保持同源语义;后续如需支持多 key (e.g. 'adminUser')
|
|
// 再扩成泛型 getStoredJSON(key) 即可。
|
|
|
|
/**
|
|
* 安全读取本地缓存中的 user(JSON) 并解析为对象。
|
|
*
|
|
* 失败场景(return null):
|
|
* - 'user' key 不存在 → uni.getStorageSync 返回 "" 或 undefined
|
|
* - 'user' 缓存损坏 / 不是合法 JSON → JSON.parse 抛错
|
|
* - 'user' 是合法 JSON 但解析后是 null(如 'null' 字符串)→ 兜底返回 null
|
|
*
|
|
* @returns {object|null} 解析成功返回 user 对象;失败返回 null
|
|
*/
|
|
export function getStoredUser() {
|
|
const userStr = uni.getStorageSync('user');
|
|
if (!userStr) return null;
|
|
try {
|
|
return JSON.parse(userStr) || null;
|
|
} catch (e) {
|
|
// warn 级别即可,不要 error —— 这是可预期的 cache miss / 损坏,不是真错
|
|
console.warn('[getStoredUser] failed to parse user storage:', e?.message || e);
|
|
return null;
|
|
}
|
|
}
|