防止接口异常导致页面报错崩溃

136 阅读1分钟

防止接口异常导致页面报错崩溃

0.前言

防止后端坑B,某次不按约定返回一个不正常的数据格式,导致事故。

1.直接解构接口数据

// 模拟处理接口拿到的data
const handleData = (data)=> {
  const { userinfo } = data;
  const { id, age } = userinfo;
}
​
handleData({})
​
// Uncaught TypeError: Cannot destructure property 'id' of 'user' as it is undefined.

如果只是简单的给默认值

const handleData = (data)=> {
  const { userinfo = {} } = data;
  const { id, name } = userinfo;
}
​
handleData({userinfo: null})
​
// Uncaught TypeError: Cannot destructure property 'id' of 'userinfo' as it is null.

userinfonull的时候还会出现报错,因为如果一个对象的属性值不是=== undefined,那么默认值就不会生效。

I think a better approach is

const handleData = (data = {}) => {
  const { user } = data;
  const { id = '', name = '' } = user || {};
}

2.直接使用接口数组数据

// 模拟处理接口拿到的data
const handleData = (data)=> {
  const { goodsList } = data;
  const temList = goodsList.map((item)=> item.goodsname)
}
handleData({userList: null})
handleData({userList: 123})
handleData({userList: [ null, undefined ]})
​
// Uncaught TypeError: goodsList.map is not a function

很显然,后端的同事又发癫了。

I think a better approach is

const handleData = (data = {}) => {
  const { goodsList = [] } = data;
​
  if (!Array.isArray(goodsList)) {
    console.warn('goodsList is not an array:', goodsList);
    return [];
  }
​
  const temList = goodsList
    .filter(item => item && typeof item === 'object')
    .map(item => item.goodsname)
    .filter(Boolean);
​
  console.log('Processed goods names:', temList);
  return temList;
};
​
// 测试各种情况
console.log(handleData({userList: null}));
console.log(handleData({userList: 123}));
console.log(handleData({userList: [ null, undefined ]}));
console.log(handleData({goodsList: [{goodsname: 'Apple'}, null, {goodsname: 'Banana'}]}));

3.为什么有时候不报错

('').name
(123).name

感觉好像会报错,事实上并没有报错。因为除了nullundefined这俩个以外,其他的基本类型都会被打包成对象,以便能使用对象的方法,所以要重点防范nullundefined

4.页面一直loading

有时候写了一个loading,async/await 报错未捕获的情况下又不处理loading就会一直loading下去。

const List = () => {
  const [loading, setLoading] = useState(false);
    
  const getData = async () => {
    setLoading(true);
    try {
      const res = await queryData();
      setLoading(false);
    } catch (error) {
      console.log('===error===',error)
      setLoading(false);
    }
  }
}
​