错误处理往往是最容易被忽略的一块,因为
这样到底什麽时候要错误处理?
为了方便讲解,我们先来复习一下错误处理的必须武器 try catch,如果你已经很熟了可以跳过这一段:
try
/catch
/finally
属於流程控制的逻辑区块(跟 if
/else
一样),以下分别介绍:
openFile();
try {
writeFile(theData); // 可能产生例外
} catch(e) {
handleError(e); // 处理可能发生的例外
} finally {
closeFile(); // 总是在 try 结束後关闭档案
}
try
throw
),就不会继续往下执行,而是跳到 catch 区块第一行开始执行。catch
finally
try
或 catch
区块执行完就会进来,用来处理一些无论有没有错误都要做的事情(比如把 loading 关掉、写 log 等)。来谈谈错误的种类,了解一下「错误」到底是什麽?才会知道该怎麽处理它:
即程序本身的 bug,错误是程序本身没写对造成的。常见的例如:
这类型的错误代表与开发者的意图背道而驰,因此没有悬念,就是一定要把它改对,通常透过开发人员工具可以轻松找到原因。
在程序本身没有 bug 的情况下,错误发生在系统本身,通常是程序与外部互动下发生,外部可能是使用者、网路远端、档案系统。常见的例如:
这类型的错误代表,通常在使用者「预想」情况下,程序是可以正常运作的,但是如果:
十笔资料可以跑,那十万笔呢?
都市可以跑,那偏乡地区呢?
json 档案可以处理,那 xml 呢?
因此,其实这类型的错误不太算是「错误」,毕竟部分的 case 都还是可以运作的,或许比较适合称呼为例外(exception)。
这类型的错误处理起来就复杂许多,需要对症下药,
let file;
try {
file = readFile(filePath);
} catch (err){
file = createFile(filePath);
}
console.log(file);
let retryCount = 0;
const retryMax = 3;
do {
try {
console.log(retryCount);
// ...
// 可能失败的 code 放这
// ...
break;
} catch (err){
console.log(err);
retryCount++;
if (retryCount >= retryMax) {
// 超过 retry 次数强制跳出
break;
} else {
// 还没超过可以再试一次
continue;
}
}
} while (true);
setLoading(true);
try {
// ...
// 可能失败的 code 放这
// ...
} catch (err){
logToDB(err);
} finally {
setLoading(false);
toast('系统不稳,请稍後再试');
}
未知的问题在 catch
处理很合理,有一些已知的问题也放在 catch
处理,但既然我都知道这边有可能会出问题了,为何不乾脆用 if/else 判断处理?
这个问题其实我也觉得稍微模糊,我的想法是,需要先去定义出,catch
究竟要接收什麽?是所有取不回资料的状况吗?还是针对非正常流程的处理?针对不同的目的,应该使用不同的处理,以下是我的一些想法
适合放在 catch
处理的:
fetch
资料途中,发生例外情况不适合放在 catch
处理的(可以用 if/else 处理):
false
,也就是使用者不授予权限时。但这也不是硬性规定,单纯是不同的想法导致不同的设计,甚至不同的 API 在处理错误的状态也都不尽相同,因此笔者认为,只要整个 app 在面对错误是一致就可以了 (比如查无资料要嘛都放 else
,要嘛都放 catch
)。
回归到开头的问题,为什麽错误处理往往是最容易被忽略的一块?
类比来说,其实错误处理很像是现实社会中的「保险」:
当然啦,错误处理跟保险还是有很多细节、情境的不同,不可完全类比,这边只是笔者有感而发XD,觉得有些事情,我们在写程序的时候会碰到,在现实生活中也会碰到。
错误/例外处理是很多开发者不太想去碰的一块,很容易只关注在「正常」,而比较少考虑「异常」。
市场上大部分的商业专案、产品,PM 当然也都是要求先有功能,毕竟没功能的话,就算有一堆 try catch 也是枉然。
但正是因为「少而重要」,才能体现出价值,如果能够在这点更谨慎,无疑是朝向「更好」的 developer 迈进!
愈深的洞穴里
藏着愈闪耀的宝石
>>: 用React刻自己的投资Dashboard Day17 - Dashboard 2.0版路由功能
当别人说你的程序是义大利面代码 (Spaghetti code),听起来很好吃,应该是称赞的意思吧!...
Some potential uses - Product identification, disa...
制作目标 搜寻选择、使用者输入 Node.js从版本7开始提供readline模组,从可读串(例如p...
在写 Vue.js 或 React 的过程,一定都会听过这个名词。 并不是所有的 component...
Abstract 相信许多人都有遇过例外处理的事件,但又不想要让内部核心的错误资讯呈现在前端上,仅记...