在未处理的错误

时间:2018-05-30 21:13:27

标签: node.js typescript express exception socket.io

我发现了几个事件,以确保在应用程序存在之前我的socket.io http服务器已正确关闭:

const app = express()
server = http.createServer(app)
io = sio(server)

process.on('SIGUSR2', shutdownServer)
process.on('SIGINT', shutdownServer)
process.on('uncaughtException', shutdownServer)

function shutdownServer() {
    io.close(() => {
        server.close(() => process.exit(1))
    })
}

现在我挑起了一个致命的错误:

let x = undefined
x.foo()

使用tsc-watch运行脚本,如下所示:

"scripts": {
    "clean": "rm -rf dist",
    "watch": "npm run clean & tsc-watch -p . --outDir ./dist --onSuccess \"node ./dist/main.js\" --onFailure \"Compile-Error\""
}

我希望在x.foo()调用之后,我的socket.io服务器关闭,并且Node.js进程存在。但由于未知原因,情况并非如此:在异常之后,我运行ps -aux | grep node | grep main.js并看到节点进程正在运行。这个节点甚至处理answear socket.io请求!

背景:更改Typescript

的检测

使用TypeScript的Node.js应用程序,我喜欢在更改时自动重新编译文件。所以我使用了tsc-watch。但是这让我很开心,因为它显示了一些奇怪的行为:首先我在保存更改的文件后随机看EADDRINUSE。通过在SIGUSR2信号上杀死服务器和节点,我可以解决这个问题。

后来我学到了很难的方法,这对异常无效。因此,如果我保存中断的代码,旧的Node进程将继续运行。这很难找到,因为在这种情况下,由于未知原因,我没有得到EADDRINUSE - 尽管旧进程在同一端口上侦听。它显示了旧过程的日志托管。

现在我修复了所有奇怪和不受欢迎的beaviours,除了未捕获的异常问题。我的解决方法是:使用ctrl + c停止观察者,使用ps在后​​台获取未停止进程的pid,杀死它们并重新启动观察程序。但那很糟糕。我只是希望tsc-watch杀死旧的进程/服务器并启动一个新的进程/服务器。根据文档,这就是它的作用:"Notes: Any child process (COMMAND) will be terminated before creating a new one."

为什么节点进程仍在运行?

但它不起作用。即使我上面的代码中没有捕获的异常处理程序也无法正常工作,我甚至不知道为什么。互联网包含许多关于uncaughtException处理程序的帖子,其中有一小部分使用process.exit()来终止进程。

这是由socket.io/express中的某些setInterval()函数引起的吗?我也浪费了很多时间,因为当你不打电话unref()时,这样的电话会一直运行。特别是对于节点终止问题,当节点多次生成并且每次创建这样的无限循环时,这将导致总混乱。但如果这是真的,那么它无法解释为什么我对{。1}}调用socket.io/express不起作用。

所以我正在寻找一种方法来杀死从我的主进程创建的所有进程,子进程和其他东西,这样我在使用close()开发期间就不会得到任何僵尸。

编辑#1

好的,我发现这只是因为COMPILE错误造成的。上面的示例导致编译错误,因为tsc-watch没有类型。如果我们这样做:

x

我们收到运行时错误,let x: any = undefined x.foo() 被称为〜>我的结束工作。但我也想处理编译错误。消息uncaughtException表示该节点似乎在这里产生子进程,也许这就是我们获得这些行为的原因。

Altough我仍然不明白为什么在这种情况下启动节点?使用spawn Compile-Error ENOENT编译错误:

  

src / main.ts(43,4):错误TS2532:对象可能是“未定义”

我认为let x = undefined在这种情况下得到了一个类型化的常量值,因为它不能与x不同。 undefined允许let x: any = undefined无法输入,这使得另一个值成为可能。

Imho这会导致编译失败,因此不会启动任何节点。这可能是x的不当行为吗?

编辑2:可能的解决方法:降级到NodeJS LTS

认识到我在RPI上的节点客户端问题较少,我看到RPI上的LTS版本(目前是8.11.2),我的开发机器有Arch Linux,因此安装了最新的10.3.0版本。我找到了nvm,一个节点的版本管理器。虽然这似乎是一个好主意,但它会导致我的npm脚本出现问题。我要在我想运行应用程序的每个盒子上安装nvm。

所以我找到了一个更好的解决方案:Node has an official npm-package,可以作为依赖项添加:

tsc-watch

现在您只需使用npm i -P node@v8-lts 来使用本地节点而不是全局安装的节点:

npx node

出于测试目的,我删除了所有信号的上述事件以及通用异常处理程序。我的第一次测试似乎运行良好,没有问题,节点10的情况不是这样。我会密切关注这一点。但似乎[user@antergos server]$ npx node --version v8.11.1 [user@antergos server]$ node --version v10.3.0 与节点10不兼容。这有点棘手,因为tsc-watch没有任何兼容性文档,所以我不知道这个事实。

0 个答案:

没有答案