diff options
author | 2023-09-07 17:11:53 -0300 | |
---|---|---|
committer | 2023-09-07 17:11:53 -0300 | |
commit | 29c5645f50a0698afb77d33009e602e187946e94 (patch) | |
tree | 055e3661da420b27bdf2be265ff4314f3f7fbc8e | |
parent | e9db9f32b14dc76d6a8e7dffab83d51ec4cf5713 (diff) | |
download | bun-29c5645f50a0698afb77d33009e602e187946e94.tar.gz bun-29c5645f50a0698afb77d33009e602e187946e94.tar.zst bun-29c5645f50a0698afb77d33009e602e187946e94.zip |
resolve promise/stream on abort always
-rw-r--r-- | src/bun.js/webcore/response.zig | 67 |
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 { |