remix-run / remix

Build Better Websites. Create modern, resilient user experiences with web fundamentals.
https://remix.run
MIT License
28.69k stars 2.43k forks source link

Node Fetch: Cannot cancel a stream that already has a reader #9222

Open 19Qingfeng opened 4 months ago

19Qingfeng commented 4 months ago

Reproduction

export const loader: LoaderFunction = async ({ context, request }) => {

  const controller = new AbortController()
  fetch('http://google/api.com', {
    signal: controller.signal,
  })
  controller.abort()

  return defer({
  })
}

System Info

node v18.12.0
remix-run/node 1.15.0

Used Package Manager

pnpm

Expected Behavior

The fetch request can be cancelled normally, but an error was caught in the catch.

Actual Behavior

#9216

I used fetch in Remix, but encountered the following issue:

image

I'm not sure how I should use fetch on the server to initiate request processing and interrupt requests after timeout.

export const loader: LoaderFunction = async ({ context, request }) => {

  const controller = new AbortController()
  fetch('http://google/api.com', {
    signal: controller.signal,
  })
  controller.abort()

  return defer({
  })
}

This may seem like a bug, but I do need to retrieve some data through fetch on the server. Is there no other way for Remix to do this?

19Qingfeng commented 4 months ago

see here on the tag of feat, would like to ask the next question for the time being no hack ending plan ?

19Qingfeng commented 4 months ago

I am not sure about the current progress of this issue, but I have used a hack approach to address it

const nodeFetch = require("node-fetch");
let fetchOverlay = false;
export function setupFetch() {
  if (!fetchOverlay) {
    globalThis.fetch = nodeFetch as any;
    fetchOverlay = true;
  }
}
19Qingfeng commented 4 months ago

I am not sure about the current progress of this issue, but I have used a hack approach to address it

const nodeFetch = require("node-fetch");
let fetchOverlay = false;
export function setupFetch() {
  if (!fetchOverlay) {
    globalThis.fetch = nodeFetch as any;
    fetchOverlay = true;
  }
}

I'm not sure what problem this will bring, but it did solve the problem temporarily