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

fetch signal abortcontroller does not work #2489

Open
sroussey opened this issue Mar 26, 2023 · 6 comments · May be fixed by #2724
Open

fetch signal abortcontroller does not work #2489

sroussey opened this issue Mar 26, 2023 · 6 comments · May be fixed by #2724
Labels
bug Something isn't working web-api Something that relates to a standard Web API

Comments

@sroussey
Copy link
Contributor

What version of Bun is running?

0.5.8

What platform is your computer?

Darwin 22.3.0 arm64 arm

What steps can reproduce the bug?

interface FetchWithTimeoutOptions extends Omit<FetchRequestInit, 'timeout'> {
  timeout: number;
}
export async function fetchWithTimeout(resource: string | URL, options?: FetchWithTimeoutOptions) {
  const { timeout = 1000, ...otheroptions } = options || {};

  const controller = new AbortController();
  const id = setTimeout(() => controller.abort(), timeout);
  let response;
  try {
    response = await fetch(resource, {
      ...otheroptions,
      signal: controller.signal,
    });
  } catch (err) {
    response = {
      ok: false,
      status: 500,
    };
  }
  clearTimeout(id);
  return response;
}

const start = Date.now();
await fetchWithTimeout("https://www.custvestor.com/", { timeout: 100 });
const end = Date.now();
console.log(`It took ${end-start}ms not 100ms`);

What is the expected behavior?

It should take 100ms

What do you see instead?

It takes a lot longer!

Additional information

No response

@sroussey sroussey added the bug Something isn't working label Mar 26, 2023
@Electroid Electroid added the web-api Something that relates to a standard Web API label Mar 27, 2023
Plecra added a commit to Plecra/bun that referenced this issue Apr 24, 2023
This appears to be a bug within the HTTPS (TLS?) connection code,
where it waits for some initial handshake before allowing timeouts
to interrupt the connection. I seen one of these fetches give up, even
from a native timeout.
@Plecra Plecra linked a pull request Apr 24, 2023 that will close this issue
@uxmaster
Copy link

@Plecra This seems to also apply to plain HTTP connections. If the connection cannot be established (all packets dropped at the destination), signals do nothing. Only the internal HTTP timeout is applied (1 minute?).

I tested AbortSignal and AbortConroller on fetch from http://127.0.0.7, while nothing was listening there. Both tests result with Signal failed! on macOS Darwin 21.6.0 x86_64 with Bun 1.0.14

const timeout = setTimeout(() => {
	console.error('Signal failed!');
	process.exit();
}, 2e3);

try {
	console.log(await fetch('http://127.0.0.7', { signal: AbortSignal.timeout(1e3) }));
}
catch (e) {
	clearTimeout(timeout);
	if (e.name === 'TimeoutError') console.log('Signal worked!');
	else console.error(e);
}

I'm also pinging @cirospaciari, since he authored #6390

@SukkaW
Copy link
Contributor

SukkaW commented Dec 26, 2023

I am facing the same issue on AbortSignal.timeout as @uxmaster on the latest bun canary build (1.0.20+05984d405) as well.

See also #7512 and #7513.

@ImLunaHey
Copy link
Contributor

Weirdly if i let this run I get Aborted! as the output but it takes the same amount of time to run.

➜  stable-diffusion-discord-bot git:(main) ✗ bun run src/file.ts
[75.02s] fetch
Aborted!
➜  stable-diffusion-discord-bot git:(main) ✗ bun run src/file.ts
[75.02s] fetch
ConnectionRefused: Unable to connect. Is the computer able to access the url?
 path: "http://192.168.1.134/"
// abort in 1 second
let controller = new AbortController();
setTimeout(() => controller.abort(), 1000);
console.time('fetch');

try {
  let response = await fetch('http://192.168.1.134', {
    signal: controller.signal,
  });
  // @ts-expect-error abc
} catch (err: Error) {
  console.timeEnd('fetch');
  if (err.name == 'AbortError') {
    // handle abort()
    console.info('Aborted!');
  } else {
    throw err;
  }
}

@ImLunaHey
Copy link
Contributor

ImLunaHey commented Dec 26, 2023

Ah, if I set timeout: false it works with the abort handler.

ignore me this doesnt work it just instantly times out. 😞

➜  stable-diffusion-discord-bot git:(main) ✗ bun run src/file.ts
[13.65ms] fetch
FailedToOpenSocket: Was there a typo in the url or port?
 path: "http://192.168.1.134/"

@drag0n-app
Copy link

I am facing the same issue on AbortSignal.timeout as @uxmaster on the latest bun canary build (1.0.20+05984d405) as well.

See also #7512 and #7513.

I'm in China and the firewall is blocking google.com, in my test code I guess fetch is not handling signal in the DNS resolution stage. I replaced google.com with a URL that is accessible and signal is fine!

@SukkaW
Copy link
Contributor

SukkaW commented Jan 2, 2024

I am facing the same issue on AbortSignal.timeout as @uxmaster on the latest bun canary build (1.0.20+05984d405) as well.
See also #7512 and #7513.

I'm in China and the firewall is blocking google.com, in my test code I guess fetch is not handling signal in the DNS resolution stage. I replaced google.com with a URL that is accessible and signal is fine!

The issue happens on GitHub Actions as well, bun just timeout indefinitely even with AbortSignal.timeout(4000).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working web-api Something that relates to a standard Web API
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants