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

(regression?) timeouts while reading a body no longer abort with a TimeoutError #3296

Open
simhnna opened this issue May 23, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@simhnna
Copy link

simhnna commented May 23, 2024

Bug Description

I'm not sure when this changed, but undici no longer throws a TimeoutError when reading the body

Reproducible By

import { fetch as undiciFetch } from 'undici';


async function test(method) {
    try {
        const signal = AbortSignal.timeout(1000);
        const res = await method('https://httpbin.org/drip?duration=2&numbytes=10&code=200&delay=0', {signal});
        try {
            await res.arrayBuffer();
        } catch (error) {
            console.log('body read timeout')
            console.log(error instanceof DOMException);
            console.log(error.code === 23);
            console.log(error);
        }
    } catch (error) {
        console.log('header read timeout')
        console.log(error instanceof DOMException);
        console.log(error.code === 23);
        console.log(error);
    }
}


await test(undiciFetch);
await test(fetch);

Expected Behavior

Both calls should abort with a TimeoutError

Logs & Screenshots

body read timeout
true
false
DOMException [AbortError]: The operation was aborted.
    at new DOMException (node:internal/per_context/domexception:53:5)
    at Fetch.abort (/home/sia/dev/platform/next-server/node_modules/undici/lib/fetch/index.js:108:15)
    at requestObject.signal.addEventListener.once (/home/sia/dev/platform/next-server/node_modules/undici/lib/fetch/index.js:189:20)
    at [nodejs.internal.kHybridDispatch] (node:internal/event_target:826:20)
    at EventTarget.dispatchEvent (node:internal/event_target:761:26)
    at abortSignal (node:internal/abort_controller:371:10)
    at AbortController.abort (node:internal/abort_controller:393:5)
    at EventTarget.abort (/home/sia/dev/platform/next-server/node_modules/undici/lib/fetch/request.js:368:16)
    at [nodejs.internal.kHybridDispatch] (node:internal/event_target:826:20)
    at EventTarget.dispatchEvent (node:internal/event_target:761:26)
body read timeout
true
true
DOMException [TimeoutError]: The operation was aborted due to timeout
    at new DOMException (node:internal/per_context/domexception:53:5)
    at Timeout._onTimeout (node:internal/abort_controller:130:9)
    at listOnTimeout (node:internal/timers:573:17)
    at process.processTimers (node:internal/timers:514:7)

Environment

node v20.12.2
undici 6.16.0

Additional context

@simhnna simhnna added the bug Something isn't working label May 23, 2024
@metcoder95
Copy link
Member

metcoder95 commented May 23, 2024

Tested with latest main without success:

const { fetch: undiciFetch } = require('undici')

async function test (method) {
  const signal = AbortSignal.timeout(1000)
  const res = await method(
    'https://httpbin.org/drip?duration=2&numbytes=10&code=200&delay=0',
    { signal }
  )
  await res.arrayBuffer()
}

test(undiciFetch).then(
  () => {
    console.log('undicifetch: done')
  },
  err => console.log('undicifetch:', err)
)
test(fetch).then(
  () => {
    console.log('fetch: done')
  },
  err => console.log('fetch:', err)
)

Outcome:

undicifetch: DOMException [TimeoutError]: The operation was aborted due to timeout
    at new DOMException (node:internal/per_context/domexception:53:5)
    at Timeout._onTimeout (node:internal/abort_controller:130:9)
    at listOnTimeout (node:internal/timers:573:17)
    at process.processTimers (node:internal/timers:514:7)
fetch: DOMException [TimeoutError]: The operation was aborted due to timeout
    at new DOMException (node:internal/per_context/domexception:53:5)
    at Timeout._onTimeout (node:internal/abort_controller:130:9)
    at listOnTimeout (node:internal/timers:573:17)
    at process.processTimers (node:internal/timers:514:7)

@simhnna
Copy link
Author

simhnna commented May 24, 2024

@metcoder95 what you posted would be the intended outcome. You're not logging if it was a header or body timeout. header timeouts appeared to throw a TimeoutError in my tests.

but today I can't replicate it any longer. Neither with undici 6.16.0 nor any later version...

According to the stacktrace the error is thrown here
at Fetch.abort (/home/sia/dev/platform/next-server/node_modules/undici/lib/fetch/index.js:108:15)
but there is no such location. The stacktrace is swallowing the web directory. it should've been
/home/sia/dev/platform/next-server/node_modules/undici/lib/web/fetch/index.js

It throws there when error is falsy. I'll try to figure out how that can happen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants