aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar cirospaciari <ciro.spaciari@gmail.com> 2023-09-07 17:11:53 -0300
committerGravatar cirospaciari <ciro.spaciari@gmail.com> 2023-09-07 17:11:53 -0300
commit29c5645f50a0698afb77d33009e602e187946e94 (patch)
tree055e3661da420b27bdf2be265ff4314f3f7fbc8e
parente9db9f32b14dc76d6a8e7dffab83d51ec4cf5713 (diff)
downloadbun-29c5645f50a0698afb77d33009e602e187946e94.tar.gz
bun-29c5645f50a0698afb77d33009e602e187946e94.tar.zst
bun-29c5645f50a0698afb77d33009e602e187946e94.zip
resolve promise/stream on abort always
-rw-r--r--src/bun.js/webcore/response.zig67
1 files changed, 62 insertions, 5 deletions
diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig
index 5cd59b06e..4766d2a2d 100644
--- a/src/bun.js/webcore/response.zig
+++ b/src/bun.js/webcore/response.zig
@@ -1386,17 +1386,74 @@ pub const Fetch = struct {
return fetch_tasklet;
}
- pub fn abortListener(this: *FetchTasklet, reason: JSValue) void {
+ pub fn abortListener(this: *FetchTasklet, err: JSValue) void {
log("abortListener", .{});
- reason.ensureStillAlive();
- this.abort_reason = reason;
- reason.protect();
+ const globalThis = this.global_this;
+ err.ensureStillAlive();
+ err.protect();
+ this.is_waiting_abort = true;
+ this.abort_reason = err;
+
this.signal_store.aborted.store(true, .Monotonic);
- this.tracker.didCancel(this.global_this);
+ this.tracker.didCancel(globalThis);
if (this.http != null) {
HTTPClient.http_thread.scheduleShutdown(this.http.?);
}
+
+ var ref = this.promise;
+
+ const promise_value = ref.valueOrEmpty();
+
+ defer ref.strong.deinit();
+
+ if (this.signal) |signal| {
+ this.signal = null;
+ signal.detach(this);
+ }
+ err.ensureStillAlive();
+
+ if (promise_value.isEmptyOrUndefinedOrNull()) {
+ log("abortListener no promise", .{});
+ if (this.readable_stream_ref.get()) |readable| {
+ readable.ptr.Bytes.onData(
+ .{
+ .err = .{ .JSValue = err },
+ },
+ bun.default_allocator,
+ );
+ return;
+ }
+ if (this.response.get()) |response_js| {
+ if (response_js.as(Response)) |response| {
+ const body = response.body;
+ if (body.value == .Locked) {
+ if (body.value.Locked.readable) |readable| {
+ readable.ptr.Bytes.onData(
+ .{
+ .err = .{ .JSValue = err },
+ },
+ bun.default_allocator,
+ );
+ return;
+ }
+ }
+
+ response.body.value.toErrorInstance(err, globalThis);
+ return;
+ }
+ }
+
+ globalThis.throwValue(err);
+ return;
+ }
+
+ log("abortListener with promise", .{});
+
+ promise_value.ensureStillAlive();
+ const promise = promise_value.asAnyPromise() orelse return;
+
+ promise.reject(globalThis, err);
}
const FetchOptions = struct {