错误处理方案

image.png

  1. /**
  2. * 如果我们有一个函数, 在调用这个函数时, 如果出现了错误, 那么我们应该是去修复这个错误.
  3. */
  4. function sum(num1, num2) {
  5. // 当传入的参数的类型不正确时, 应该告知调用者一个错误
  6. if (typeof num1 !== "number" || typeof num2 !== "number") {
  7. // return undefined
  8. throw "parameters is error type~"
  9. }
  10. return num1 + num2
  11. }
  12. // 调用者(如果没有对错误进行处理, 那么程序会直接终止)
  13. // console.log(sum({ name: "why" }, true))
  14. console.log(sum(20, 30))
  15. console.log("后续的代码会继续运行~")

throw关键字

throw 表达式就是在 throw 后面可以跟上一个表达式来表示具体的异常信息。
throw 后面可以跟基本数据类型,也可以跟对象,主要是跟对象,因为表达的信息多。

  1. class HYError {
  2. constructor(errorCode, errorMessage) {
  3. this.errorCode = errorCode // 错误代号
  4. this.errorMessage = errorMessage // 错误信息
  5. }
  6. }
  7. function foo(type) {
  8. console.log("foo函数开始执行")
  9. if (type === 0) {
  10. // 1.抛出一个字符串类型(基本的数据类型)
  11. // throw "error"
  12. // 2.比较常见的是抛出一个对象类型
  13. // throw { errorCode: -1001, errorMessage: "type不能为0~" }
  14. // 3.也可以自定义抛出的类:创建类, 并且创建这个类对应的对象
  15. throw new HYError(-1001, "type不能为0~")
  16. // 强调: 如果函数中已经抛出了异常, 那么后续的代码都不会继续执行了
  17. console.log("foo函数后续的代码")
  18. }
  19. console.log("foo函数结束执行")
  20. }
  21. foo(0)
  22. // foo函数开始执行
  23. // G:\JavaScript\demo\index.js:19
  24. // throw new HYError(-1001, "type不能为0~")
  25. // ^
  26. // HYError { errorCode: -1001, errorMessage: 'type不能为0~' }

Error 类型

事实上,JavaScript 已经给我们提供了一个 Error 类,我们可以直接创建这个类的对象:
Error 包含三个属性:

  • messsage:创建Error对象时传入的message;
  • name:Error 的名称,通常和类的名称一致;
  • stack:整个 Error 的错误信息,包括 message 和函数的调用链,这个链是从加载模块开始的;

    • 当我们直接打印 Error 对象时,打印的就是 stack 属性; ```javascript function foo(type) { console.log(“foo函数开始执行”)

    if (type === 0) { // 可以修改错误名称 const err = new Error(‘构造函数中默认的是错误信息,比如:不能为 0’) err.name = ‘类型错误’ // 也可以修改 stack 整个 Error 错误信息 throw err }

    console.log(“foo函数结束执行”) }

foo(0)

// foo函数开始执行 // G:\JavaScript\demo\index.js:9 // throw err // ^

// 类型错误: 构造函数中默认的是错误信息,比如:不能为 0 // at foo (G:\JavaScript\demo\index.js:6:17) // at Object. (G:\coderwhy\JavaScript\demo\index.js:15:1) // at Module._compile (internal/modules/cjs/loader.js:1072:14) // at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) // at Module.load (internal/modules/cjs/loader.js:937:32) // at Function.Module._load (internal/modules/cjs/loader.js:778:12) // at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12) // at internal/main/run_main_module.js:17:47 // node 以模块加载代码开始

  1. Error有一些自己的子类,表示了更具体的错误类型,我们也可以继承 Error 从而定义自己错误类型类。
  2. - RangeError:下标值越界时使用的错误类型;
  3. - SyntaxError:解析语法错误时使用的错误类型;
  4. - TypeError:出现类型错误时,使用的错误类型;
  5. ```javascript
  6. function foo(type) {
  7. console.log("foo函数开始执行")
  8. if (type === 0) {
  9. throw new TypeError('不能为0')
  10. }
  11. console.log("foo函数结束执行")
  12. }
  13. foo(0)
  14. // foo函数开始执行
  15. // TypeError: 不能为0
  16. // 略

JS 处理异常的过程

image.png

try-catch 异常捕获

很多情况下当出现异常时,我们并不希望程序直接推出,而是希望可以正确的处理异常:这个时候我们就可以使用try catch

  1. function foo(type) {
  2. if (type === 0) {
  3. throw new Error("foo error message~")
  4. }
  5. }
  6. // 两种处理方法:
  7. // 1.第一种是不处理, 那么异常会进一步的抛出, 直到最顶层的调用
  8. // 如果在最顶层也没有对这个异常进行处理, 那么我们的程序就会终止执行, 并且报错
  9. // 2.使用try catch来捕获异常
  10. function bar() {
  11. try {
  12. foo(0)
  13. console.log("bar函数后续的继续运行")
  14. } catch(err) { // catch 可以接收一个参数,该参数固定为 Error 类的实例对象
  15. console.log("err:", err.message)
  16. } finally {
  17. console.log("finally代码执行~, close操作")
  18. }
  19. }
  20. function test() {
  21. // 因为异常会层层向上抛出,所以也可以在上层进行异常捕获
  22. // try {
  23. bar()
  24. // } catch (error) {
  25. // console.log("error:", error)
  26. // }
  27. }
  28. function demo() {
  29. test()
  30. }
  31. demo()
  32. // 异常被捕获,不影响后续代码的执行
  33. console.log("后续的代码执行~")
  34. // err: foo error message~
  35. // finally代码执行~, close操作
  36. // 后续的代码执行~

在ES10(ES2019)中,catch后面绑定的error可以省略。
如果有一些必须要执行的代码,我们可以使用finally来执行:finally表示最终一定会被执行的代码结构;

  • 注意:如果 try 和 finally 中都有返回值,那么会使用 finally 当中的返回值; ```javascript function foo(type) { if (type === 0) { throw new Error(‘foo error message~’) } }

function bar() { try { foo(1) console.log(‘bar函数后续的继续运行’)

  1. return 123

} catch (err) { console.log(‘err:’, err.message) } finally { console.log(‘finally代码执行~, close操作’)

  1. return 456

} }

console.log(bar()) // 456

console.log(‘后续的代码执行~’)

// bar函数后续的继续运行
// finally代码执行~, close操作 // 456 // 后续的代码执行~ ```