有没有一种方法可以抛出类似于ENOENT或EPIPE的系统错误?

3

我希望测试我的流程,确保它对 EPIPE 错误具有弹性,因为我们在生产环境中看到了这些错误,除了缺少一些日志记录外,它们似乎并没有任何问题。

if (process.env.TESTFAIL != null) {
    setTimeout(function() {
        throw new Error('EPIPE');
    }, 1000);
}

然而那看起来不太一样,EPIPE 错误看起来像:

Error: write EPIPE at errnoException (net.js:770:11)

我也尝试过使用throw new Error({code: 'EPIPE', errno: -3})等方式,但是效果不太一样。

有没有一种方法可以从Node.js对象中获取代码/消息并抛出系统错误?

2个回答

3
不,无法精确“抛出”一个ENOENTEPIPE或类似的错误。
简单来说,它们并不是JavaScript或编程语言中的错误或异常。它们是系统错误代码,当某些条件满足时由系统调用或标准库例程返回(或存储)的整数。(通常在Unix或Linux系统上,尽管其他操作系统也采用了相同的命名法。)
如果您想以有意义的方式重新创建它们以进行测试,您需要创建触发它们的条件。例如,当您尝试打开不存在的文件(路径)时会发生ENOENT。在测试代码中尝试这样做可以重新创建导致ENOENT出现的条件。您可以开始然后断开一个管道以获得EPIPE。这是重新创建这些条件的唯一有意义的方法。
在JavaScript级别看到一个称为EPIPE的错误是可能的,可以抛出EPIPE值(32)或嵌入EPIPE值或字符串'EPIPE'Error。这些更高级别的错误表现只是真正错误条件的结果。如果您希望您的代码针对底层问题进行测试,通常必须创建底层情况。

通常情况下,您需要创建基础情况。对于EPIPE有什么想法吗?似乎这是最有可能突然出现的情况(在写入日志时等)。 - jcollum
当然。启动到外部进程的管道,然后在数据仍在传输时使用信号(例如SIGINTSIGKILL)终止外部进程。与大多数单元测试相比,这是一件丑陋/复杂的事情,并且可能属于集成测试范畴。但这样做对于测试EPIPE处理既必要又充分。像Unix yes(它发出无限序列)这样的实用程序可以成为此类测试的有用外部工具。 - Jonathan Eunice
实际上这些错误在node中存在,但似乎没有在公共API中导出。https://github.com/nodejs/node/blob/v13.3.0/lib/internal/errors.js - Andre Miras

1

你可以使用类似的解决方法

let err = new Error('myMessage')
err.code = 'EPIPE'
err.errno = -3
throw err;

或者使用一个类

class SystemError {
 constructor(message, code, errno) {
   let err = new Error(message)
   err.code = 'EPIPE'
   err.errno = -3
   return err;
 }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接