99%的顺序都没有斟酌的收集非常

本文由云+社区宣布

绝大多数顺序只斟酌了接口一般事情的场景,而用户在运用我们的产物时碰到的种种异常,全都丢在看似 ok 的 try catch 中。假如没有做好异常的兼容和兜底处置惩罚,会极大的影响用户体验,严峻的还会带来平安和资损风险。

接口异常,一般能够分为以下三类:

  • CGI 逻辑失足。如挪用方入参缺失类营业逻辑报错;
  • 效劳不稳定。如效劳器不稳定致使 nginx 种种 500、502,cgi 途径调解致使的 404
  • 用户收集环境差。如,收集不稳定、网速慢、运营商挟制等

那末,我们在写代码时,怎样疾速的模仿这些接口异常,做好顺序的兼容处置惩罚呢?

本日向人人引见收集调试神器 whistle 的收集异常调试要领,假如你还没用过 whistle,请参考《8102 年的顺序员不需要 Hosts 和 Fiddler》。

假定我们有以下前端页面 index.html,安排在本身的当地途径:

<p id="success" style="color:green;"></p>
<p id="fail" style="color:red;"></p>
<script>
  fetch(`/mock?r=${Math.random()}`)
    .then(response => {
      return response.json()
    })
    .then(v => {
      document.getElementById('success').innerHTML = v.data;
    }).catch(err => {
      document.getElementById('fail').innerHTML = err.message;
    })
</script>

接下来,翻开 whistle Rules 设置面板 http://127.0.0.1:8899/#rules ,设置模仿的 demo page 和 mock CGI:

*/mock file://({"code":0,"data":"success"}) # 设置 mock cgi 为模仿的 json 数据
example.com file:///Users/kaiye/Projects/Markdown/20181213/ # 设置恣意域名到当地 demo 目次,这里注重替换成本身的途径

翻开 http://example.com ,一般逻辑下页面展现出了绿色的 success ,如今我们最先到场一些收集异常。

1、营业逻辑异常处置惩罚

比方 CGI 没有返回 data 字段,而是返回了一个毛病码 code 和对应的 message,针对这类营业逻辑异常我们只需在第二个 then 中做好 code 值的推断即可(注重,这里的 code、message、data 只是示例,现实营业 CGI 中的 JSON 构造体的字段名极能够差别):

fetch(`/mock?r=${Math.random()}`)
  .then(response => response.json())
  .then((v) => {
    // 营业逻辑异常处置惩罚
    if (v.code !== 0) {
      return Promise.reject(new Error(`ERROR_LOGIC_CODE:${v.code}`));
    }
    document.getElementById('success').innerHTML = v.data;
  })
  .catch((err) => {
    document.getElementById('fail').innerHTML = err.message;
  });

响应的 whistle 设置以下:

*/mock file://({"code":12345,"message":"some_logic_error"}) # 模仿营业逻辑异常

2、效劳器异常处置惩罚

假如效劳器直接抛出了 502 毛病码,我们愿望代码能给用户提醒的同时,再做一个异常上报。

fetch(`/mock?r=${Math.random()}`)
  .then((response) => {
    // 效劳器异常处置惩罚
    if (response.ok) {
      return response.json();
    }
    return Promise.reject(new Error(`ERROR_STATUS_CODE:${response.status}`));
  })
  .then((v) => {
    // 营业逻辑异常处置惩罚
    if (v.code !== 0) {
      return Promise.reject(new Error(`ERROR_LOGIC_CODE:${v.code}`));
    }
    document.getElementById('success').innerHTML = v.data;
  })
  .catch((err) => {
    const [type, value] = err.message.split(':');
    // 异常范例上报
    console.log(type, value);
    document.getElementById('fail').innerHTML = err.message;
  });

经由过程 whistle 的模仿设置以下:

*/mock statusCode://502 # 模仿 HTTP 状况码异常

3、接口被挟制注入

假如 CGI 被运营商挟制注入,能够致使接口返回一个不合法的 JSON 构造,最前面的 response.json() 会抛异常,我们能够提早 catch 住:

fetch(`/mock?r=${Math.random()}`).then((response) => {
  // 效劳器异常处置惩罚
  if (response.ok) {
    return (
      response
        .json()
        // 接口数据解码异常处置惩罚
        .catch(err => Promise.reject(new Error('ERROR_DECODE_JSON')))
    );
  }
  return Promise.reject(new Error(`ERROR_STATUS_CODE:${response.status}`));
});

whistle 模仿设置以下:

*/mock file://(<div>hijacking</div>{"code":0,"data":"success"}) # 模仿接口被挟制注入 1

借助 htmlAppendvalues 设置,能够模仿更庞杂的注入示例:

*/mock file://({"code":0,"data":"success"}) htmlAppend://{hijacking.html} # 模仿接口被挟制注入 2

<script>
alert(‘hijacking’)
</script>

4、用户收集不稳定

假如我们要模仿要求发出 10 秒后断网或收集不通的状况,能够经由过程 whistle 如许设置:

*/mock reqDelay://10000 enable://abort # 模仿 10 秒超时后收集不通

让用户苦苦守候 10 秒,再报错的体验太蹩脚。我们能够封装一个能设置超时时候的要求发送函数,同时把上面提到的毛病异常都一同设置进来。

<p id="success" style="color:green;"></p>
<p id="fail" style="color:red;"></p>
<script>
  function myFetch(url, configOptions) {
    const options = Object.assign(
      {
        timeout: 3000
      },
      configOptions
    )
    const { timeout } = options
    return new Promise((resolve, reject) => {
      // 超时异常处置惩罚
      const timer = setTimeout(() => {
        reject(new Error(`ERROR_TIMEOUT:${timeout}`))
      }, timeout)
      fetch(url, options)
        .then(data => {
          clearTimeout(timer)
          resolve(data)
        })
        .catch(err => {
          clearTimeout(timer)
          reject(err)
        })
    })
      .then(response => {
        // 效劳器异常处置惩罚
        if (response.ok) {
          return (
            response
              .json()
              // 接口数据解码异常处置惩罚
              .catch(err => Promise.reject(new Error('ERROR_DECODE_JSON')))
          )
        } else {
          return Promise.reject(
            new Error(`ERROR_STATUS_CODE:${response.status}`)
          )
        }
      })
      .then(v => {
        // 营业逻辑异常处置惩罚
        if (v.code !== 0) {
          return Promise.reject(new Error(`ERROR_LOGIC_CODE:${v.code}`))
        } else {
          return v.data
        }
      })
      .catch(err => {
        const [type, value] = err.message.split(':')
        // 异常范例上报
        console.log(type, value)
        return Promise.reject(err)
      })
  }
  myFetch(`/mock?r=${Math.random()}`)
    .then(data => {
      document.getElementById('success').innerHTML = data
    })
    .catch(err => {
      document.getElementById('fail').innerHTML = err.message
    })
</script>

如许,自定义的 myFetch 只需关注营业详细逻辑,针对差别的 catch error 做对应的处置惩罚。

除以上提到的协定命令字外,whistle 还支撑 resSpeed 用于模仿低网速传输(单元:kb/s),tpl 协定则能够依据要求传入参数来动态模仿差别的数据。在 Frames 面板,还能够对 WebSocket/Socket 要求举行停息、耽误等收集异常的模仿。

小顺序 fetch API 完成

末了,留一道思考题。

最近微信小顺序开辟异常火,小顺序原生供应的 wx.request API 能用于发送 HTTPS 要求,请在它的基本之上举行封装,支撑 promise 挪用和 timeout 超时时候定义(小顺序默许的要求超时定义在 app.json 中,不够天真),并针对以上提到的 HTTP 状况码异常、接口挟制注入、慢收集、无收集状况等种种收集异常举行兼容处置惩罚。

迎接留言分享你的代码完成

此文已由作者受权腾讯云+社区宣布

    原文作者:腾讯云加社区
    原文地址: https://segmentfault.com/a/1190000017525152
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞