You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中jwt-decode引发未处理Promise拒绝警告问题

React Native检查Token有效性时的未处理Promise拒绝警告问题

问题描述

我在React Native中实现了Stack Overflow上Jafar的Token有效性检查方案,代码逻辑能正常运行,但控制台始终抛出「Possible Unhandled Promise Rejection」警告,错误类型为InvalidTokenError。尝试过用try/catch和回调处理Promise拒绝,警告仍未消除,希望找到问题原因和解决办法。

相关代码

// navigation
const navigation = useNavigation()

// config request: check token expiry-validity
const checkTokenValidity = async (next) => {
  const token = state && state.token ? state.token : ''
  let err

  const decodedToken = jwt_decode(token)
  console.log('Decoded Token-----> ', decodedToken)
  let currentDate = new Date()

  if (decodedToken.exp * 1000 < currentDate.getTime()) {
    err.message = 'Token has expired.'
    await AsyncStorage.removeItem('auth-rn')
    setState({ user: {}, token: '' })
    next(err)
  } else {
    console.log('Valid token')
  }
}

// run checkTokenValidity
checkTokenValidity((err) => {
  if (err) {
    console.log(`Token error: ${err.message}`)
    alert(
      'Your session is older than 7 days and it has expired. You´ll be redirected to log-in now.'
    )
    navigation.navigate('SignIn')
  }
  return
}) 

控制台警告信息

WARN Possible Unhandled Promise Rejection (id: 0):
[InvalidTokenError: 无效的token:undefined不是一个对象(计算 'e.replace' 时)]

问题原因

  1. 未捕获jwt_decode的同步错误:当token为空字符串时,jwt_decode会直接抛出InvalidTokenError同步错误。由于你的函数是async函数,未捕获的同步错误会被自动包装成Promise拒绝,导致控制台出现未处理Promise拒绝的警告。
  2. 错误对象未初始化:你只声明了let err但未初始化,直接给err.message赋值会触发Cannot set properties of undefined的潜在错误,进一步加剧Promise处理的混乱。

解决办法

修改代码,确保捕获所有可能的错误,正确初始化错误对象,并完善Promise的错误处理逻辑:

修改后的代码

// navigation
const navigation = useNavigation()

// config request: check token expiry-validity
const checkTokenValidity = async (next) => {
  const token = state?.token || ''
  try {
    // 提前判断空token,直接触发错误分支
    if (!token) {
      throw new Error('Token不存在')
    }

    const decodedToken = jwt_decode(token)
    console.log('Decoded Token-----> ', decodedToken)
    const currentDate = new Date()

    if (decodedToken.exp * 1000 < currentDate.getTime()) {
      const err = new Error('Token已过期')
      await AsyncStorage.removeItem('auth-rn')
      setState({ user: {}, token: '' })
      next(err)
    } else {
      console.log('Token有效')
      // 无错误时调用回调传入null,确保逻辑完整
      next(null)
    }
  } catch (error) {
    // 捕获jwt_decode抛出的错误或自定义错误
    console.log('Token验证错误:', error.message)
    await AsyncStorage.removeItem('auth-rn')
    setState({ user: {}, token: '' })
    next(error)
  }
}

// run checkTokenValidity
checkTokenValidity((err) => {
  if (err) {
    console.log(`Token错误: ${err.message}`)
    alert('你的会话已超过7天,已过期。即将跳转到登录页面。')
    navigation.navigate('SignIn')
  }
})

关键修改点

  • 用state?.token || ''简化token取值逻辑,更简洁安全。
  • 增加空token判断,提前抛出错误,避免jwt_decode处理空值。
  • 用try/catch包裹整个验证流程,捕获所有同步/异步错误,确保Promise拒绝被处理。
  • 初始化错误对象为Error实例,避免undefined赋值错误。
  • 在catch分支统一处理所有错误,清空存储和状态后调用回调通知上层。
  • 有效token时调用next(null),确保回调逻辑的完整性。

内容的提问来源于stack exchange,提问作者Carlos del Ríño Francés

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 10:35:20