在线工具
网站地图    收藏    合作   
<

快捷菜单 返回顶部

node中文API-Error错误

Error 错误#

中英对照

在 Node.js 中运行的应用程序通常会遇到四类错误:

  • 标准的 JavaScript 错误,例如 <EvalError><SyntaxError><RangeError><ReferenceError><TypeError><URIError>
  • 由底层操作系统约束触发的系统错误,例如尝试打开不存在的文件或尝试通过关闭的套接字发送数据。
  • 由应用程序代码触发的用户指定的错误。
  • AssertionError 是特殊的错误类,当 Node.js 检测到不应该发生的异常逻辑违规时会触发。 这些通常由 assert 模块引发。

Node.js 引发的所有 JavaScript 和系统错误都继承自标准的 JavaScript <Error> 类(或者是其实例),并且保证至少提供该类上可用的属性。

错误的传播和拦截#

中英对照

Node.js 支持多种机制来传播和处理应用程序运行时发生的错误。 如何报告和处理这些错误完全取决于 Error 的类型和调用的 API 的风格。

所有的 JavaScript 错误都作为异常处理,使用标准的 JavaScript throw 机制立即生成并抛出错误。 这些是使用 JavaScript 语言提供的 try…catch 构造处理的。

// 由于 z 未定义,因此抛出 ReferenceError。
try {
  const m = 1;
  const n = m + z;
} catch (err) {
  // 在此处理错误。
}

任何使用 JavaScript throw 机制都会引发异常,必须使用 try…catch 处理,否则 Node.js 进程将立即退出。

除了少数例外,同步的 API(任何不接受 callback 函数的阻塞方法,例如 fs.readFileSync)都使用 throw 来报告错误。

异步的 API 中发生的错误可以以多种方式报告:

  • 大多数接受 callback 函数的异步方法将接受作为第一个参数传给该函数的 Error 对象。 如果第一个参数不是 null 并且是 Error 的实例,则发生了应该处理的错误。

    const fs = require('fs');
    fs.readFile('a file that does not exist', (err, data) => {
      if (err) {
        console.error('There was an error reading the file!', err);
        return;
      }
      // 否则处理数据
    });
  • 当在 EventEmitter 对象上调用异步方法时,错误可以路由到该对象的 'error' 事件。

    const net = require('net');
    const connection = net.connect('localhost');
    
    // 向流中添加 'error' 事件句柄:
    connection.on('error', (err) => {
      // 如果连接被服务器重置,
      // 或者根本无法连接,或者连接遇到任何类型的错误,
      // 则错误将发送到这里。
      console.error(err);
    });
    
    connection.pipe(process.stdout);
  • Node.js API 中的一些典型的异步方法可能仍然使用 throw 机制来引发必须使用 try…catch 处理的异常。 没有此类方法的完整列表;请参阅每种方法的文档以确定所需的适当错误处理机制。

'error' 事件机制的使用最常见于基于流基于事件触发器的 API,其本身代表了一系列随时间推移的异步操作(而不是单个操作可能通过或失败)。

对于所有的 EventEmitter 对象,如果未提供 'error' 事件句柄,则将抛出错误,导致 Node.js 进程报告未捕获的异常并崩溃,除非:domain 模块使用得当或已为 'uncaughtException' 事件注册句柄。

const EventEmitter = require('events');
const ee = new EventEmitter();

setImmediate(() => {
  // 这将导致进程崩溃,
  // 因为没有添加 'error' 事件句柄。
  ee.emit('error', new Error('This will crash'));
});

以这种方式产生的错误不能使用 try…catch 拦截,因为其抛出后调用代码已经退出。

开发者必须参考每种方法的文档,以确定这些方法引发的错误是如何传播的。

错误优先的回调#

中英对照

Node.js 核心 API 暴露的大多数异步方法都遵循称为错误优先回调的惯用模式。 使用这种模式,回调函数作为参数传给方法。 当操作完成或出现错误时,回调函数将使用 Error 对象(如果有)作为第一个参数传入。 如果没有出现错误,则第一个参数将作为 null 传入。

const fs = require('fs');

function errorFirstCallback(err, data) {
  if (err) {
    console.error('There was an error', err);
    return;
  }
  console.log(data);
}

fs.readFile('/some/file/that/does-not-exist', errorFirstCallback);
fs.readFile('/some/file/that/does-exist', errorFirstCallback);

JavaScript try…catch 机制不能用于拦截异步 API 产生的错误。 初学者的一个常见错误是尝试在错误优先的回调中使用 throw

// 这行不通:
const fs = require('fs');

try {
  fs.readFile('/some/file/that/does-not-exist', (err, data) => {
    // 错误的假设:在这里抛出...
    if (err) {
      throw err;
    }
  });
} catch (err) {
  // 这不会捕获抛出的错误!
  console.error(err);
}

这不起作用,因为传给 fs.readFile() 的回调函数是异步调用的。 当回调被调用时,周围的代码(包括 try…catch 块)已经退出。 大多数情况下,在回调中抛出错误会使 Node.js 进程崩溃。 如果启用了,或者已经在 process.on('uncaughtException') 注册了句柄,则可以拦截此类错误。

Error#

中英对照

通用的 JavaScript <Error> 对象,不表示发生错误的任何具体情况。 Error 对象捕获"堆栈跟踪",详细说明代码中实例化 Error 的点,并可能提供错误的文本描述。

Node.js 生成的所有错误,包括所有系统和 JavaScript 错误,都将是 Error 类的实例或继承自 Error 类。

new Error(message)#

中英对照

创建新的 Error 对象并将 error.message 属性设置为提供的文本消息。 如果对象作为 message 传入,则通过调用 message.toString() 生成文本消息。 error.stack 属性将代表代码中调用 new Error() 的点。 堆栈跟踪依赖于 V8 的堆栈跟踪 API。 堆栈跟踪仅扩展到 (a) 同步代码执行的开始,或 (b) 属性 Error.stackTraceLimit 给定的帧数,以较小者为准。

Error.captureStackTrace(targetObject[, constructorOpt])#

中英对照

targetObject 上创建 .stack 属性,访问时返回表示调用 Error.captureStackTrace() 的代码中的位置的字符串。

const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack;  // 类似于`new Error().stack`

跟踪的第一行将以 ${myObject.name}: ${myObject.message} 为前缀。

可选的 constructorOpt 参数接受一个函数。 如果给定,则所有 constructorOpt 以上的帧,包括 constructorOpt,都将从生成的堆栈跟踪中省略。

constructorOpt 参数对于向用户隐藏错误生成的实现细节很有用。 例如:

function MyError() {
  Error.captureStackTrace(this, MyError);
}

// 如果不将 MyError 传给 captureStackTrace,
// 则 MyError 帧将显示在 .stack 属性中。
// 通过传入构造函数,则省略该帧,并保留其下方的所有帧。
new MyError().stack;

Error.stackTraceLimit#

中英对照

Error.stackTraceLimit 属性指定堆栈跟踪收集的堆栈帧数(无论是由 new Error().stack 还是 Error.captureStackTrace(obj) 生成)。

默认值为 10,但可以设置为任何有效的 JavaScript 数值。 更改将影响值更改后捕获的任何堆栈跟踪。

如果设置为非数字值,或设置为负数,则堆栈跟踪将不会捕获任何帧。

error.code#

中英对照

error.code 属性是标识错误类型的字符串标签。 error.code 是识别错误的最稳定方式。 它只会在 Node.js 的主要版本之间发生变化。 相比之下,error.message 字符串可能会在任何版本的 Node.js 之间发生变化。 有关特定代码的详细信息,请参阅 Node.js 错误码

error.message#

中英对照

error.message 属性是通过调用 new Error(message) 设置的错误的字符串描述。 传给构造函数的 message 也会出现在 Error 的堆栈跟踪的第一行,但是在 Error 对象创建后更改此属性可能不会更改堆栈跟踪的第一行(例如,当读取 error.stack 时 在此属性更改之前)。

const err = new Error('The message');
console.error(err.message);
// 打印: The message

error.stack#

中英对照

error.stack 属性是描述代码中实例化 Error 的点的字符串。

Error: Things keep happening!
   at /home/gbusey/file.js:525:2
   at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21)
   at Actor.<anonymous> (/home/gbusey/actors.js:400:8)
   at increaseSynergy (/home/gbusey/actors.js:701:6)

第一行格式为 <error class name>: <error message>,后面是一系列堆栈帧(每行以 "at " 开头)。 每一帧都描述了代码中导致错误生成的调用点。 V8 尝试为每个函数显示名称(通过变量名、函数名、或对象方法名),但偶尔会找不到合适的名称。 如果 V8 无法确定函数的名称,则只会显示该帧的位置信息。 否则,将显示确定的函数名称,括号中会附加位置信息。

帧仅为 JavaScript 函数生成。 例如,如果执行同步通过名为 cheetahify 的 C++ 插件函数,该函数本身调用 JavaScript 函数,则表示 cheetahify 调用的帧将不会出现在堆栈跟踪中:

const cheetahify = require('./native-binding.node');

function makeFaster() {
  // `cheetahify()` 同步地调用 speedy。
  cheetahify(function speedy() {
    throw new Error('oh no!');
  });
}

makeFaster();
// 会抛出:
//   /home/gbusey/file.js:6
//       throw new Error('oh no!');
//           ^
//   Error: oh no!
//       at speedy (/home/gbusey/file.js:6:11)
//       at makeFaster (/home/gbusey/file.js:5:3)
//       at Object.<anonymous> (/home/gbusey/file.js:10:1)
//       at Module._compile (module.js:456:26)
//       at Object.Module._extensions..js (module.js:474:10)
//       at Module.load (module.js:356:32)
//       at Function.Module._load (module.js:312:12)
//       at Function.Module.runMain (module.js:497:10)
//       at startup (node.js:119:16)
//       at node.js:906:3

位置信息将是以下之一:

  • native, 如果帧代表 V8 内部的调用(如 [].forEach)。
  • plain-filename.js:line:column, 如果帧代表 Node.js 内部调用
  • 如果帧代表用户程序中的调用(使用 CommonJS 模块系统)或其依赖项,则为 /absolute/path/to/file.js:line:column
  • 如果帧代表用户程序中的调用(使用 ES 模块系统)或其依赖关系,则为 <transport-protocol>:///url/to/module/file.mjs:line:column

访问 error.stack 属性时,延迟生成表示堆栈跟踪的字符串。

堆栈跟踪捕获的帧数以 Error.stackTraceLimit 或当前事件循环刻度上的可用帧数中的较小者为界。

AssertionError#

中英对照

表示断言的失败。 详情见 Class: assert.AssertionError

RangeError#

中英对照

表示提供的参数不在函数可接受值的集合或范围内;无论是数字范围,还是在给定函数参数的选项集之外。

require('net').connect(-1);
// 抛出 "RangeError: "port" option should be >= 0 and < 65536: -1"

Node.js 将立即生成并抛出 RangeError 实例作为参数验证的一种形式。

ReferenceError#

中英对照

表示正在尝试访问未定义的变量。 此类错误通常表示代码中存在拼写错误或程序损坏。

虽然客户端代码可能会产生和传播这些错误,但实际上只有 V8 会这样做。

doesNotExist;
// 抛出 ReferenceError,doesNotExist 不是此程序中的变量。

除非应用程序动态生成和运行代码,否则 ReferenceError 实例表明代码或其依赖项中存在错误。

SyntaxError#

中英对照

表示程序不是有效的 JavaScript。 这些错误只能作为代码评估的结果生成和传播。 代码评估可能是 evalFunctionrequirevm 的结果。 这些错误几乎始终表明程序损坏。

try {
  require('vm').runInThisContext('binary ! isNotOk');
} catch (err) {
  // 'err' 将是 SyntaxError。
}

SyntaxError 实例在创建它们的上下文中是不可恢复的,它们只能被其他上下文捕获。

SystemError#

中英对照

Node.js 在其运行时环境中发生异常时会生成系统错误。 这些通常发生在应用程序违反操作系统约束时。 例如,如果应用程序尝试读取不存在的文件,则会发生系统错误。

  • address <string> 如果存在,则为网络连接失败的地址
  • code <string> 字符串错误码
  • dest <string> 如果存在,则为报告文件系统错误时的文件路径目标
  • errno <number> 系统提供的错误号
  • info <Object> 如果存在,则为关于错误情况的额外细节
  • message <string> 系统提供的人类可读的错误描述
  • path <string> 如果存在,则为报告文件系统错误时的文件路径
  • port <number> 如果存在,则为不可用的网络连接端口
  • syscall <string> 触发错误的系统调用名称

error.address#

中英对照

如果存在,则 error.address 是描述网络连接失败的地址的字符串。

error.code#

中英对照

error.code 属性是表示错误代码的字符串。

error.dest#

中英对照

如果存在,则 error.dest 是报告文件系统错误时的文件路径目标。

error.errno#

中英对照

error.errno 属性是对应于 libuv Error handling 中定义的错误码的负数。

在 Windows 上,系统提供的错误号将由 libuv 规范化。

要获取错误码的字符串表示,则使用 util.getSystemErrorName(error.errno)

error.info#

中英对照

如果存在,则 error.info 是包含错误情况详细信息的对象。

error.message#

中英对照

error.message 是系统提供的人类可读的错误描述。

error.path#

中英对照

如果存在,则 error.path 是包含相关无效路径名的字符串。

error.port#

中英对照

如果存在,则 error.port 是不可用的网络连接端口。

error.syscall#

中英对照

error.syscall 属性是描述失败的系统调用的字符串。

常见的系统错误#

中英对照

这是编写 Node.js 程序时经常遇到的系统错误列表。 有关完整的列表,请参阅 errno(3) 手册页

  • EACCES(权限被拒绝):试图以文件访问权限禁止的方式访问文件。

  • EADDRINUSE(地址已被使用):尝试将服务器(nethttp、或 https)绑定到本地地址失败,因为本地系统上的另一台服务器已经占用了该地址。

  • ECONNREFUSED(连接被拒绝):由于目标机器主动拒绝,无法建立连接。 这通常是由于尝试连接到在外部主机上处于非活动状态的服务。

  • ECONNRESET(对等方重置连接):连接被对等方强行关闭。。 这通常是由于超时或重新启动导致远程套接字上的连接丢失造成的。 通常通过 httpnet 模块遇到。

  • EEXIST(文件存在):现有文件是要求目标不存在的操作的目标。

  • EISDIR(是目录):操作期望文件,但给定的路径名​​是目录。

  • EMFILE(系统中打开的文件太多):已达到系统上允许的文件描述符的最大数量,并且在至少一个描述符被关闭之前无法满足对另一个描述符的请求。 同时打开多个文件时会遇到这种情况,尤其是在进程的文件描述符限制较低的系统(特别是 macOS)上。 要弥补低限制,则在将运行 Node.js 进程的同一个 shell 中运行 ulimit -n 2048

  • ENOENT(无此文件或目录):通常由 fs 操作引发,以指示指定路径名的组件不存在。 给定路径找不到任何实体(文件或目录)。

  • ENOTDIR(不是目录):给定路径名的组件存在,但不是期望的目录。 通常由 fs.readdir 引起。

  • ENOTEMPTY(目录不为空):有条目的目录是需要空目录的操作目标,通常是 fs.unlink

  • ENOTFOUND(域名系统查找失败):表示 EAI_NODATAEAI_NONAME 的域名系统失败。 这不是标准的 POSIX 错误。

  • EPERM(不允许操作):试图执行需要提升权限的操作。

  • EPIPE(断开的管道):对没有进程读取数据的管道、套接字或 FIFO 的写操作。 通常发生在 nethttp 层,表示正在写入的流的远程端已关闭。

  • ETIMEDOUT(操作超时):连接或发送请求失败,因为连接方在一段时间后没有正确地响应。 通常发生在 httpnet。 通常表明 socket.end() 没有被正确地调用。

TypeError#

中英对照

表示提供的参数不是允许的类型。 例如,将函数传给期望字符串为 TypeError 的参数。

require('url').parse(() => { });
// 抛出 TypeError,因为它期望字符串。

Node.js 将立即生成并抛出 TypeError 实例作为参数验证的一种形式。

异常与错误#

中英对照

JavaScript 异常是由于无效操作或作为 throw 语句的目标而抛出的值。 虽然不要求这些值是 Error 的实例或从 Error 继承的类,但 Node.js 或 JavaScript 运行时抛出的所有异常都将是 Error 的实例。

一些异常在 JavaScript 层是不可恢复的。 此类异常将始终导致 Node.js 进程崩溃。 示例包括 C++ 层中的 assert() 检查或 abort() 调用。

OpenSSL 错误#

中英对照

源自 cryptotls 的错误属于 Error 类,除了标准的 .code.message 属性外,可能还有一些额外的 OpenSSL 特定属性。

error.opensslErrorStack#

中英对照

可以为 OpenSSL 库中错误源自的位置提供上下文的错误数组。

error.function#

中英对照

错误源自的 OpenSSL 函数。

error.library#

中英对照

错误源自的 OpenSSL 库。

error.reason#

中英对照

描述错误原因的人类可读的字符串。

Node.js 错误码#

ABORT_ERR#

中英对照

当操作中止时使用(通常使用 AbortController)。

不使用 AbortSignal 的 API 通常不会引发此代码的错误。

此代码未使用 Node.js 错误使用的常规 ERR_* 约定,以便与网络平台的 AbortError 兼容。

ERR_AMBIGUOUS_ARGUMENT#

中英对照

函数参数的使用方式表明函数签名可能会被误解。 当 assert.throws(block, message) 中的 message 参数与 block 抛出的错误消息匹配时,则由 assert 模块抛出错误,因为这种用法表明用户认为 message 是预期的消息,而不是 block 不抛出时 AssertionError 将显示的消息。

ERR_ARG_NOT_ITERABLE#

中英对照

需要可迭代的参数(即适用于 for...of 循环的值),但未提供给 Node.js API。

ERR_ASSERTION#

中英对照

特殊类型的错误,每当 Node.js 检测到不应该发生的异常逻辑违规时就会触发。 这些通常由 assert 模块引发。

ERR_ASYNC_CALLBACK#

中英对照

试图将不是函数的东西注册为 AsyncHooks 回调。

ERR_ASYNC_TYPE#

中英对照

异步资源的类型无效。 如果使用公共的嵌入器 API,则用户还可以定义自己的类型。

ERR_BROTLI_COMPRESSION_FAILED#

中英对照

传给 Brotli 流的数据未成功压缩。

ERR_BROTLI_INVALID_PARAM#

中英对照

在构建 Brotli 流期间传入了无效的参数键。

ERR_BUFFER_CONTEXT_NOT_AVAILABLE#

中英对照

尝试从插件或嵌入器代码创建 Node.js Buffer 实例,而在与 Node.js 实例无关的 JS 引擎上下文中。 传给 Buffer 方法的数据将在方法返回时被释放。

当遇到此错误时,创建 Buffer 实例的一种可能的替代方法是创建普通的 Uint8Array,它仅在生成的对象的原型上有所不同。 Uint8Array 通常在 Buffer 所在的所有的 Node.js 核心 API 中被接受;它们在所有上下文中都可用。

ERR_BUFFER_OUT_OF_BOUNDS#

中英对照

尝试了超出 Buffer 范围的操作。

ERR_BUFFER_TOO_LARGE#

中英对照

已尝试创建大于最大允许大小的 Buffer

ERR_CANNOT_WATCH_SIGINT#

中英对照

Node.js 无法监视 SIGINT 信号。

ERR_CHILD_CLOSED_BEFORE_REPLY#

中英对照

在父进程收到回复之前子进程已关闭。

ERR_CHILD_PROCESS_IPC_REQUIRED#

中英对照

当在没有指定进程间通信通道的情况下衍生子进程时使用。

ERR_CHILD_PROCESS_STDIO_MAXBUFFER#

中英对照

当主进程试图从子进程的标准错误或标准输出读取数据、并且数据的长度比 maxBuffer 选项长时使用。

ERR_CLOSED_MESSAGE_PORT#

中英对照

曾试图在关闭状态下使用 MessagePort 实例,通常是在调用 .close() 之后。

ERR_CONSOLE_WRITABLE_STREAM#

中英对照

Console 在没有 stdout 流的情况下被实例化,或者 Console 有不可写的 stdoutstderr 流。

ERR_CONSTRUCT_CALL_INVALID#

中英对照

调用了不可调用的类构造函数。

ERR_CONSTRUCT_CALL_REQUIRED#

中英对照

在没有 new 的情况下调用了类的构造函数。

ERR_CONTEXT_NOT_INITIALIZED#

中英对照

传入 API 的虚拟机上下文尚未初始化。 这可能发生在上下文创建过程中发生(并被捕获)错误时,例如,当分配失败或在创建上下文时达到最大调用堆栈大小时。

ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED#

中英对照

请求的客户端证书引擎不受所使用的 OpenSSL 版本支持。

ERR_CRYPTO_ECDH_INVALID_FORMAT#

中英对照

format 参数的无效值被传给 crypto.ECDH()getPublicKey() 方法。

ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY#

中英对照

key 参数的无效值已传给 crypto.ECDH()computeSecret() 方法。 这意味着公钥位于椭圆曲线之外。

ERR_CRYPTO_ENGINE_UNKNOWN#

中英对照

无效的加密引擎标识符被传给 require('crypto').setEngine()

ERR_CRYPTO_FIPS_FORCED#

中英对照

使用了 --force-fips 命令行参数,但尝试在 crypto 模块中启用或禁用 FIPS 模式。

ERR_CRYPTO_FIPS_UNAVAILABLE#

中英对照

尝试启用或禁用 FIPS 模式,但 FIPS 模式不可用。

ERR_CRYPTO_HASH_FINALIZED#

中英对照

hash.digest() 被多次调用。 对于 Hash 对象的每个实例,调用 hash.digest() 方法的次数不得超过一次。

ERR_CRYPTO_HASH_UPDATE_FAILED#

中英对照

hash.update() 因任何原因失败。 这应该很少发生,如果有的话。

ERR_CRYPTO_INCOMPATIBLE_KEY#

中英对照

给定的加密密钥与尝试的操作不兼容。

ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS#

中英对照

所选的公钥或私钥编码与其他选项不兼容。

ERR_CRYPTO_INITIALIZATION_FAILED#

中英对照

加密子系统初始化失败。

ERR_CRYPTO_INVALID_AUTH_TAG#

中英对照

提供了无效的身份验证标签。

ERR_CRYPTO_INVALID_COUNTER#

中英对照

为计数器模式密码提供了无效的计数器。

ERR_CRYPTO_INVALID_CURVE#

中英对照

提供了无效的椭圆曲线。

ERR_CRYPTO_INVALID_DIGEST#

中英对照

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com