Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: defer errors with setImmediate #3081

Merged
merged 1 commit into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions lib/api/readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ class BodyReadable extends Readable {
// tick as it is created, then a user who is waiting for a
// promise (i.e micro tick) for installing a 'error' listener will
// never get a chance and will always encounter an unhandled exception.
// - tick => process.nextTick(fn)
// - micro tick => queueMicrotask(fn)
queueMicrotask(() => {
setImmediate(() => {
callback(err)
})
}
Expand Down
90 changes: 72 additions & 18 deletions test/request-timeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ test('request timeout with readable body', async (t) => {
test('body timeout', async (t) => {
t = tspl(t, { plan: 2 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -102,7 +105,10 @@ test('body timeout', async (t) => {
test('overridden request timeout', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -136,7 +142,10 @@ test('overridden request timeout', async (t) => {
test('overridden body timeout', async (t) => {
t = tspl(t, { plan: 2 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -172,7 +181,10 @@ test('overridden body timeout', async (t) => {
test('With EE signal', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -209,7 +221,10 @@ test('With EE signal', async (t) => {
test('With abort-controller signal', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -246,7 +261,10 @@ test('With abort-controller signal', async (t) => {
test('Abort before timeout (EE)', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -283,7 +301,10 @@ test('Abort before timeout (EE)', async (t) => {
test('Abort before timeout (abort-controller)', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -320,7 +341,10 @@ test('Abort before timeout (abort-controller)', async (t) => {
test('Timeout with pipelining', async (t) => {
t = tspl(t, { plan: 3 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -363,7 +387,10 @@ test('Timeout with pipelining', async (t) => {
test('Global option', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -399,7 +426,10 @@ test('Global option', async (t) => {
test('Request options overrides global option', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -460,7 +490,10 @@ test('client.destroy should cancel the timeout', async (t) => {
test('client.close should wait for the timeout', async (t) => {
t = tspl(t, { plan: 2 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -542,7 +575,10 @@ test('Validation', async (t) => {
test('Disable request timeout', async (t) => {
t = tspl(t, { plan: 2 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -586,7 +622,10 @@ test('Disable request timeout', async (t) => {
test('Disable request timeout for a single request', async (t) => {
t = tspl(t, { plan: 2 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -630,7 +669,10 @@ test('Disable request timeout for a single request', async (t) => {
test('stream timeout', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -668,7 +710,10 @@ test('stream timeout', async (t) => {
test('stream custom timeout', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -708,7 +753,10 @@ test('stream custom timeout', async (t) => {
test('pipeline timeout', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -765,7 +813,10 @@ test('pipeline timeout', async (t) => {
test('pipeline timeout', async (t) => {
t = tspl(t, { plan: 1 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down Expand Up @@ -824,7 +875,10 @@ test('pipeline timeout', async (t) => {
test('client.close should not deadlock', async (t) => {
t = tspl(t, { plan: 2 })

const clock = FakeTimers.install({ shouldClearNativeTimers: true })
const clock = FakeTimers.install({
shouldClearNativeTimers: true,
toFake: ['setTimeout', 'clearTimeout']
})
after(() => clock.uninstall())

const orgTimers = { ...timers }
Expand Down