From 3d7795ce39b58df4d1dbfeb3b769784e707cd186 Mon Sep 17 00:00:00 2001
From: Divy Srivastava <dj.srivastava23@gmail.com>
Date: Tue, 26 Nov 2024 17:47:56 +0530
Subject: [PATCH 1/2] fix(ext/fetch): don't throw when `bodyUsed` inspect after
 request upgrade

Fixes https://github.com/denoland/deno/issues/27083
---
 ext/fetch/22_body.js     |  9 +++++--
 tests/unit/serve_test.ts | 52 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/ext/fetch/22_body.js b/ext/fetch/22_body.js
index c7e977c0b434c6..21a0e99e8054fd 100644
--- a/ext/fetch/22_body.js
+++ b/ext/fetch/22_body.js
@@ -286,8 +286,13 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
        */
       get() {
         webidl.assertBranded(this, prototype);
-        if (this[bodySymbol] !== null) {
-          return this[bodySymbol].consumed();
+        try {
+          if (this[bodySymbol] !== null) {
+            return this[bodySymbol].consumed();
+          }
+        } catch (e) {
+          // Request is closed.
+          return true;
         }
         return false;
       },
diff --git a/tests/unit/serve_test.ts b/tests/unit/serve_test.ts
index 7d8c6ca06d1d37..f5896bc64b26c1 100644
--- a/tests/unit/serve_test.ts
+++ b/tests/unit/serve_test.ts
@@ -4327,3 +4327,55 @@ Deno.test({
 
   await server.shutdown();
 });
+
+// https://github.com/denoland/deno/issues/27083
+Deno.test(
+  { permissions: { net: true } },
+  async function httpServerWebSocketInspectRequest() {
+    const ac = new AbortController();
+    const listeningDeferred = Promise.withResolvers<void>();
+    const doneDeferred = Promise.withResolvers<void>();
+    const server = Deno.serve({
+      handler: (request) => {
+        const {
+          response,
+          socket,
+        } = Deno.upgradeWebSocket(request);
+
+        socket.onopen = () => {
+          Deno.inspect(request); // should not throw
+        };
+        socket.onerror = (e) => {
+          console.error(e);
+          fail();
+        };
+        socket.onmessage = (m) => {
+          socket.send(m.data);
+          socket.close(1001);
+        };
+        socket.onclose = () => doneDeferred.resolve();
+        return response;
+      },
+      port: servePort,
+      signal: ac.signal,
+      onListen: onListen(listeningDeferred.resolve),
+      onError: createOnErrorCb(ac),
+    });
+
+    await listeningDeferred.promise;
+    const def = Promise.withResolvers<void>();
+    const ws = new WebSocket(`ws://localhost:${servePort}`);
+    ws.onmessage = (m) => assertEquals(m.data, "foo");
+    ws.onerror = (e) => {
+      console.error(e);
+      fail();
+    };
+    ws.onclose = () => def.resolve();
+    ws.onopen = () => ws.send("foo");
+
+    await def.promise;
+    await doneDeferred.promise;
+    ac.abort();
+    await server.finished;
+  },
+);

From d22b2228886328c52f08ca81275abf8d09456dc6 Mon Sep 17 00:00:00 2001
From: Divy Srivastava <dj.srivastava23@gmail.com>
Date: Tue, 26 Nov 2024 17:48:53 +0530
Subject: [PATCH 2/2] pre lint

---
 ext/fetch/22_body.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ext/fetch/22_body.js b/ext/fetch/22_body.js
index 21a0e99e8054fd..a34758d19a532c 100644
--- a/ext/fetch/22_body.js
+++ b/ext/fetch/22_body.js
@@ -290,7 +290,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
           if (this[bodySymbol] !== null) {
             return this[bodySymbol].consumed();
           }
-        } catch (e) {
+        } catch (_) {
           // Request is closed.
           return true;
         }