@JunQiu
2018-09-18T12:57:42.000000Z
字数 3332
阅读 1425
summary_2018/07 language_js think
### 自定义错误function UserError(message) {this.message = message || '默认信息';this.name = 'UserError';}// 继承Error对象UserError.prototype = new Error();UserError.prototype.constructor = UserError;### 异常的处理try_catch_finally/throw##throw语句的作用是手动中断程序执行,抛出一个错误。## try_catch1、一旦发生错误,程序就中止执行了,不再往下执行。JavaScript 提供了try...catch结构,允许对错误进行处理,选择是否往下执行。2、一旦捕获错误,JavaScript引擎就立即把代码的执行转到catch代码块,不再只想try中的语句try {throw new Error('出错了!');} catch (e) {console.log(e.name + ": " + e.message);console.log(e.stack);}// 对不同类型的错误进行处理try {foo.bar();} catch (e) {if (e instanceof EvalError) {console.log(e.name + ": " + e.message);} else if (e instanceof RangeError) {console.log(e.name + ": " + e.message);}// ...}## finallytry...catch结构允许在最后添加一个finally代码块,表示不管是否出现错误,都必需在最后运行的语句。!!!Tips:return语句的执行是排在finally代码之前,只是等finally代码执行完毕后才返回。var count = 0;function countUp() {try {return count;} finally {count++;}}countUp() // 0但是finally语句块中的return可能会覆盖,catch中的returnfunction f() {try {console.log(0);throw 'bug';} catch(e) {console.log(1);return true; // 这句原本会延迟到 finally 代码块结束再执行console.log(2); // 不会运行} finally {console.log(3);return false; // 这句会覆盖掉前面那句 returnconsole.log(4); // 不会运行}console.log(5); // 不会运行}var result = f();013false
## 前言在业务开发中,必然会遇到异常或错误,良好的异常/错误处理能够使代码的结构更加清晰,处理更加清晰,提高项目的健壮行。## 当遇到异常/错误的时候是否需要进行处理我们可能遇到不一样的错误,有可修复的,不可修复的,或者需要返回给用户,其实感觉这是一个比较复杂的情况,因为在不同的任务,我们可能根据项目的实际情况有不同的处理方式,比如:1、一些可以修复的已知的错误/异常,比如输入的类型需要的是number,输入的是字符串,我们可以在Catch中进行处理,使程序正常运行,并记录日志2、不可修复的错误:(1)需要结束资源(如数据库连接),我们可以使用finaly来完成。(2)需要给用户返回信息,可以捕获错误/异常后,结束任务,或者抛给上层进行处理,但都需要返回用户相关错误信息(3)不需要处理类型,让系统/服务器自己处理## 关于错误/异常处理的一些建议1、良好的使用自定义错误,当原始的错误类型不能描述产生的错误时,最好使用自定义错误来更加清楚的描述所产生的错误2、永远不要吞下异常当捕获异常时,必须进行处理,而不是吞下错误,那样会导致任务失败的原因,可以使用日志记录,或者抛出错误给使用者try {}catch (e) {logger.../throw err}3、捕获错误或者异常时,最好捕获特定的类型,使错误或异常描述更加清晰4、始终完整的返回异常,以便完整的返回错误,便于追踪错误原因,比如在抛出异常时try {throw new Error()}catch (Error) {//错误throw new Error(Error.message)//正确throw new Error(Error)}5、记录异常/错误或者抛出它们,但不同时执行同时抛出和记录异常/错误会导致日志中出现重复的错误记录,不便于日志的分析6、永远不要在finally块中抛出异常,记录日志finally的设计细想我认为在于处理一些因为异常/无异常情况下的收尾工作,比如资源的清理try {}catch (Error) {}finally {//数据库、网络连接、其他资源的一些关闭}7、请记住返回占用的资源。如果不打算处理异常,可以使用try_finally做最后的资源清理try {}finally {//数据库、网络连接、其他资源的一些关闭}8、尽早的捕获错误/异常可以尽早处理,或者退出程序的执行比如:1)验证用户2)插入用户3)验证地址4)插入地址5)如果出现问题则回滚所有内容1)验证用户2)验证地址3)插入用户4)插入地址5)如果出现问题则回滚所有内容9、始终在单个日志消息中包含有关异常的所有信息LOGGER.debug("Using cache sector A");LOGGER.debug("Using retry sector B");虽然在日志比较少的地方可能并不能看出来,但在没秒几十万条时,两条日志消息的距离可能相差几百条,十分难找到,不利于排查错误。10、使用模版方法来处理异常/错误,减少代码的冗余try {} catch (e)//处理异常的方法dealException(e)}
