Skip to content

Unreferenced timer started in uncaughtException handler fires immediately if exception was thrown from inside a timer #19970

Closed
@novemberborn

Description

@novemberborn
  • Version: v4.8.7, v6.12.3, v8.11.0, v9.11.1
  • Platform: MacOS 10.13.4
  • Subsystem: Timers

I have an uncaughtException handler which performs asynchronous cleanup. This cleanup may only take a certain amount of time, after which the process is forcibly exited. This time limitation is implemented through an unreferenced setTimeout.

If an uncaught exception is thrown from inside another timer, then my cleanup timeout fires instantly.

Here's a reproduction:

'use strict'

process.on('uncaughtException', err => {
  console.error('caught exception', err)

  let start = Date.now()
  const timer = setTimeout(() => {
    console.error('timeout duration %sms', Date.now() - start)
  }, 1000).unref()
  console.error('created timer')
})

setTimeout(() => {
  throw new Error('trigger')
}, 1000)

setTimeout(() => {}, 5000) // keep process alive
$ node test.js

caught exception Error: trigger
    at Timeout.setTimeout [as _onTimeout] (/private/var/folders/2_/qczp184x76b2nl034sq5hvxw0000gn/T/tmp.iAigvol9mj/test.js:12:9)
    at ontimeout (timers.js:466:11)
    at tryOnTimeout (timers.js:304:5)
    at Timer.listOnTimeout (timers.js:267:5)
created timer
timeout duration 2ms

The behavior is as expected when the timer is not unreferenced.

Metadata

Metadata

Assignees

No one assigned

    Labels

    timersIssues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions