NodeJs-Errors

 后端   小卒子   2024-09-02 22:07   110
  nodejs

Node.js的Errors模块和相关机制提供了详细的错误处理方法。在Node.js中,错误是Error对象的实例,代表在代码执行期间发生的问题。Error对象有多种类型,适用于不同的场景。

1. 引入 Error 对象

在Node.js中,Error是全局对象,不需要引入或加载任何模块。你可以直接使用它来创建和处理错误。

2. Error 对象的基础

Error对象的基本用法如下:

const error = new Error('Something went wrong');
console.error(error);

2.1 Error 构造函数

  • new Error([message[, fileName[, lineNumber]]])Error对象可以用new关键字创建。

    • message: 一个描述错误的字符串(可选)。
    • fileName: 指定错误发生的文件的名称(可选,通常不需要)。
    • lineNumber: 指定错误发生的行号(可选,通常不需要)。

示例:

const error = new Error('An unexpected error occurred');
console.error(error.message); // 输出: An unexpected error occurred
console.error(error.name); // 输出: Error
console.error(error.stack); // 输出: 错误的堆栈跟踪

3. Error 对象的属性

  1. message

    错误消息的字符串,描述了错误的具体内容。

    示例:

    const error = new Error('Invalid input');
    console.log(error.message); // 输出: Invalid input
    
  2. name

    错误的名称,通常是错误的类型,默认为Error。当使用子类(如TypeErrorReferenceError)时,name属性会自动更新为相应的类型。

    示例:

    const error = new Error('An error occurred');
    console.log(error.name); // 输出: Error
    
    const typeError = new TypeError('Type mismatch');
    console.log(typeError.name); // 输出: TypeError
    
  3. stack

    错误的堆栈跟踪(stack trace),包含错误发生时的调用堆栈信息。stack属性是一个字符串,通常包括Error的名称、message和堆栈信息。

    示例:

    function faultyFunction() {
      throw new Error('Something went wrong');
    }
    
    try {
      faultyFunction();
    } catch (error) {
      console.error(error.stack);
    }
    

4. 内置错误类型

Node.js定义了多个内置的错误类型,这些类型继承自Error对象,并提供更具体的错误描述:

  1. EvalError

    用于标识eval()函数的使用问题。现代JavaScript很少使用这个错误类型,因为eval()的使用被认为是不安全的。

    try {
      throw new EvalError('Evaluation failed');
    } catch (e) {
      console.error(e.name); // 输出: EvalError
      console.error(e.message); // 输出: Evaluation failed
    }
    
  2. RangeError

    当一个数值不在其允许的范围内时抛出。例如,Arraylength属性设置为负值。

    try {
      const arr = new Array(-1);
    } catch (e) {
      console.error(e.name); // 输出: RangeError
      console.error(e.message); // 输出: Invalid array length
    }
    
  3. ReferenceError

    当引用一个不存在的变量时抛出。例如,使用一个未定义的变量。

    try {
      console.log(nonExistentVariable);
    } catch (e) {
      console.error(e.name); // 输出: ReferenceError
      console.error(e.message); // 输出: nonExistentVariable is not defined
    }
    
  4. SyntaxError

    当JavaScript解析器遇到代码语法错误时抛出。例如,函数声明错误。

    try {
      eval('function x( {}');
    } catch (e) {
      console.error(e.name); // 输出: SyntaxError
      console.error(e.message); // 输出: Unexpected token '{'
    }
    
  5. TypeError

    当变量或参数不是预期类型时抛出。例如,将非函数类型调用为函数。

    try {
      null.f();
    } catch (e) {
      console.error(e.name); // 输出: TypeError
      console.error(e.message); // 输出: null is not an object
    }
    
  6. URIError

    当使用全局URI处理函数时,URI格式不正确时抛出。例如,decodeURI()encodeURI()

    try {
      decodeURI('%');
    } catch (e) {
      console.error(e.name); // 输出: URIError
      console.error(e.message); // 输出: URI malformed
    }
    
  7. AssertionError (来自assert模块)

    当使用assert模块进行断言时,如果断言失败,会抛出这个错误。

    const assert = require('assert');
    
    try {
      assert.strictEqual(1, 2);
    } catch (e) {
      console.error(e.name); // 输出: AssertionError
      console.error(e.message); // 输出: Expected values to be strictly equal:
                                // 1 !== 2
    }
    

5. 自定义错误类

在Node.js中,你可以创建自定义错误类来扩展Error对象,提供更详细的错误信息:

class CustomError extends Error {
  constructor(message) {
    super(message);
    this.name = this.constructor.name; // 设置错误名称为类名
  }
}

try {
  throw new CustomError('This is a custom error');
} catch (e) {
  console.error(e.name); // 输出: CustomError
  console.error(e.message); // 输出: This is a custom error
  console.error(e.stack); // 输出: 自定义错误的堆栈信息
}

6. 捕获和处理错误

错误处理是Node.js编程的核心部分。Node.js中的常见错误处理模式包括:

6.1 同步代码中的错误

对于同步代码中的错误,可以使用try/catch块捕获错误:

try {
  // 可能会抛出错误的代码
  throw new Error('Something went wrong!');
} catch (error) {
  console.error('Caught error:', error.message);
}

6.2 异步代码中的错误

  1. 回调函数中的错误处理

    异步回调函数通常接受一个err参数,如果有错误发生,err将是一个Error对象。

    const fs = require('fs');
    
    fs.readFile('nonexistentFile.txt', (err, data) => {
      if (err) {
        console.error('Error reading file:', err.message);
        return;
      }
      console.log('File data:', data);
    });
    
  2. Promise中的错误处理

    使用Promise处理异步操作时,可以使用.catch()方法来处理错误。

    const fs = require('fs').promises;
    
    fs.readFile('nonexistentFile.txt')
      .then((data) => {
        console.log('File data:', data);
      })
      .catch((err) => {
        console.error('Error reading file:', err.message);
      });
    
  3. async/await中的错误处理

    使用async/await语法处理异步操作时,可以将await语句包裹在try/catch块中。

    const fs = require('fs').promises;
    
    async function readFile() {
      try {
        const data = await fs.readFile('nonexistentFile.txt');
        console.log('File data:', data);
      } catch (err) {
        console.error('Error reading file:', err.message);
      }
    }
    
    readFile();
    

7. 全局错误处理

Node.js提供了一些全局错误处理方法来捕获未捕获的异常:

  1. process.on('uncaughtException', callback)

    当一个错误没有被捕获时,uncaughtException事件被触发。使用此方法时要谨慎,因为未捕获的异常可能导致Node.js进程进入不可恢复的状态。

    process.on('uncaughtException', (err) => {
      console.error('Uncaught exception:', err);
    });
    
    throw new Error('This is an uncaught exception');
    
  2. process.on('unhandledRejection', callback)

    当一个Promise被拒绝但没有被.catch()处理时,unhandledRejection事件被触发。

    process.on('unhandledRejection', (reason, promise) => {
      console.error
    
    

('Unhandled Rejection at:', promise, 'reason:', reason);
});

Promise.reject(new Error('This is an unhandled rejection'));


### 8. 小结

Node.js提供了强大的错误处理机制,包括内置的错误类型和自定义错误类型的能力。通过使用正确的错误处理模式,可以确保Node.js应用程序的健壮性和稳定性。无论是同步代码、异步回调、`Promise`或`async/await`,都应该考虑适当的错误处理策略,避免未处理的错误导致应用程序崩溃。