From 44f252539a94cae765bf4a8ca27327490b94c9bf Mon Sep 17 00:00:00 2001 From: Don Isaac Date: Wed, 9 Apr 2025 13:27:51 -0700 Subject: [PATCH] fix: mark `JSPromise.rejectedPromiseValue` as deprecated (#18549) ### What does this PR do? `JSPromise.rejectedPromiseValue` does not notify the VM about the promise it creates, meaning unhandled rejections created this way do not trigger `unhandledRejection`. This is leading to accidental error suppression in (likely) a lot of places. Additionally it returns a `JSValue` when really it should be returning a `*JSPromise`, making Zig bindings more type-safe. This PR renames `rejectedPromiseValue` to `dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM` and marks it as deprecated. It does _not_ modify code calling this function, meaning no behavior changes should occur. We should slowly start replacing its usages with `rejectedPromise` ## Changelog - Rename `rejectedPromiseValue` to `dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM` - Mark `JSPromise.asValue` as deprecated. It takes a `*JSGlobalObject` but never uses it. New code should use `toJS()` - Refactors `blob` to make null checks over `destination_blob.source` a release assertion - `ErrorBuilder.reject` uses `rejectedPromiseValue` when 1.3 feature flag is enabled --- src/bun.js/api/BunObject.zig | 4 +-- src/bun.js/api/bun/subprocess.zig | 2 +- src/bun.js/api/server.zig | 14 ++++---- src/bun.js/bindings/JSPromise.zig | 20 ++++++++--- src/bun.js/bindings/bindings.cpp | 2 ++ src/bun.js/node/node_fs_binding.zig | 2 +- src/bun.js/webcore/blob.zig | 55 ++++++++++++++--------------- src/bun.js/webcore/fetch.zig | 32 ++++++++--------- src/bun.js/webcore/streams.zig | 2 +- src/codegen/generate-node-errors.ts | 6 +++- src/s3/client.zig | 4 +-- 11 files changed, 79 insertions(+), 64 deletions(-) diff --git a/src/bun.js/api/BunObject.zig b/src/bun.js/api/BunObject.zig index d36ed22edc..1bcec556f8 100644 --- a/src/bun.js/api/BunObject.zig +++ b/src/bun.js/api/BunObject.zig @@ -867,7 +867,7 @@ pub fn resolve(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun const arguments = callframe.arguments_old(3); const value = doResolve(globalObject, arguments.slice()) catch { const err = globalObject.tryTakeException().?; - return JSC.JSPromise.rejectedPromiseValue(globalObject, err); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalObject, err); }; return JSC.JSPromise.resolvedPromiseValue(globalObject, value); } @@ -881,7 +881,7 @@ export fn Bun__resolve(global: *JSGlobalObject, specifier: JSValue, source: JSVa const value = doResolveWithArgs(global, specifier_str, source_str, is_esm, true, false) catch { const err = global.tryTakeException().?; - return JSC.JSPromise.rejectedPromiseValue(global, err); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(global, err); }; return JSC.JSPromise.resolvedPromiseValue(global, value); diff --git a/src/bun.js/api/bun/subprocess.zig b/src/bun.js/api/bun/subprocess.zig index 4f54bb7b20..fd3d374e03 100644 --- a/src/bun.js/api/bun/subprocess.zig +++ b/src/bun.js/api/bun/subprocess.zig @@ -1773,7 +1773,7 @@ pub fn getExited( return JSC.JSPromise.resolvedPromiseValue(globalThis, JSValue.jsNumber(signal.toExitCode() orelse 254)); }, .err => |err| { - return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); }, else => { const promise = JSC.JSPromise.create(globalThis).asValue(globalThis); diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index dae3266d54..49487b80e6 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -5724,13 +5724,13 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp JSC.markBinding(@src()); if (this.config.onRequest == .zero) { - return JSPromise.rejectedPromiseValue(ctx, ZigString.init("fetch() requires the server to have a fetch handler").toErrorInstance(ctx)); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, ZigString.init("fetch() requires the server to have a fetch handler").toErrorInstance(ctx)); } const arguments = callframe.arguments_old(2).slice(); if (arguments.len == 0) { const fetch_error = WebCore.Fetch.fetch_error_no_args; - return JSPromise.rejectedPromiseValue(ctx, ZigString.init(fetch_error).toErrorInstance(ctx)); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, ZigString.init(fetch_error).toErrorInstance(ctx)); } var headers: ?*JSC.FetchHeaders = null; @@ -5751,7 +5751,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp if (temp_url_str.len == 0) { const fetch_error = JSC.WebCore.Fetch.fetch_error_blank_url; - return JSPromise.rejectedPromiseValue(ctx, ZigString.init(fetch_error).toErrorInstance(ctx)); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, ZigString.init(fetch_error).toErrorInstance(ctx)); } var url = URL.parse(temp_url_str); @@ -5785,7 +5785,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp if (Blob.get(ctx, body__, true, false)) |new_blob| { body = .{ .Blob = new_blob }; } else |_| { - return JSPromise.rejectedPromiseValue(ctx, ZigString.init("fetch() received invalid body").toErrorInstance(ctx)); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, ZigString.init("fetch() received invalid body").toErrorInstance(ctx)); } } } @@ -5807,7 +5807,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp const fetch_error = JSC.WebCore.Fetch.fetch_type_error_strings.get(js.JSValueGetType(ctx, first_arg.asRef())); const err = JSC.toTypeError(.ERR_INVALID_ARG_TYPE, "{s}", .{fetch_error}, ctx); - return JSPromise.rejectedPromiseValue(ctx, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, err); } var request = Request.new(existing_request); @@ -5820,11 +5820,11 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp ) catch |err| this.globalThis.takeException(err); if (response_value.isAnyError()) { - return JSC.JSPromise.rejectedPromiseValue(ctx, response_value); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, response_value); } if (response_value.isEmptyOrUndefinedOrNull()) { - return JSC.JSPromise.rejectedPromiseValue(ctx, ZigString.init("fetch() returned an empty value").toErrorInstance(ctx)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, ZigString.init("fetch() returned an empty value").toErrorInstance(ctx)); } if (response_value.asAnyPromise() != null) { diff --git a/src/bun.js/bindings/JSPromise.zig b/src/bun.js/bindings/JSPromise.zig index 80fc7fed96..25e551286f 100644 --- a/src/bun.js/bindings/JSPromise.zig +++ b/src/bun.js/bindings/JSPromise.zig @@ -13,13 +13,14 @@ pub const JSPromise = opaque { rejected = 2, }; - extern fn JSC__JSPromise__asValue(arg0: *JSPromise, arg1: *JSGlobalObject) JSValue; extern fn JSC__JSPromise__create(arg0: *JSGlobalObject) *JSPromise; extern fn JSC__JSPromise__isHandled(arg0: *const JSPromise, arg1: *VM) bool; extern fn JSC__JSPromise__reject(arg0: *JSPromise, arg1: *JSGlobalObject, JSValue2: JSValue) void; extern fn JSC__JSPromise__rejectAsHandled(arg0: *JSPromise, arg1: *JSGlobalObject, JSValue2: JSValue) void; extern fn JSC__JSPromise__rejectAsHandledException(arg0: *JSPromise, arg1: *JSGlobalObject, arg2: ?*JSC.Exception) void; extern fn JSC__JSPromise__rejectedPromise(arg0: *JSGlobalObject, JSValue1: JSValue) *JSPromise; + /// **DEPRECATED** This function does not notify the VM about the rejection, + /// meaning it will not trigger unhandled rejection handling. Use JSC__JSPromise__rejectedPromise instead. extern fn JSC__JSPromise__rejectedPromiseValue(arg0: *JSGlobalObject, JSValue1: JSValue) JSValue; extern fn JSC__JSPromise__resolve(arg0: *JSPromise, arg1: *JSGlobalObject, JSValue2: JSValue) void; extern fn JSC__JSPromise__resolvedPromise(arg0: *JSGlobalObject, JSValue1: JSValue) *JSPromise; @@ -27,6 +28,7 @@ pub const JSPromise = opaque { extern fn JSC__JSPromise__result(arg0: *JSPromise, arg1: *VM) JSValue; extern fn JSC__JSPromise__setHandled(arg0: *JSPromise, arg1: *VM) void; extern fn JSC__JSPromise__status(arg0: *const JSPromise, arg1: *VM) JSPromise.Status; + extern fn JSC__JSPromise__wrap(*JSC.JSGlobalObject, *anyopaque, *const fn (*anyopaque, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue) JSC.JSValue; pub fn Weak(comptime T: type) type { return struct { @@ -172,7 +174,9 @@ pub const JSPromise = opaque { } }; - extern fn JSC__JSPromise__wrap(*JSC.JSGlobalObject, *anyopaque, *const fn (*anyopaque, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue) JSC.JSValue; + pub fn toJS(this: *JSPromise) JSValue { + return JSValue.fromCell(this); + } pub fn wrap( globalObject: *JSGlobalObject, @@ -205,7 +209,7 @@ pub const JSPromise = opaque { } if (value.isAnyError()) { - return rejectedPromiseValue(globalObject, value); + return dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalObject, value); } return resolvedPromiseValue(globalObject, value); @@ -241,7 +245,11 @@ pub const JSPromise = opaque { return JSC__JSPromise__rejectedPromise(globalThis, value); } - pub fn rejectedPromiseValue(globalThis: *JSGlobalObject, value: JSValue) JSValue { + /// **DEPRECATED** use `JSPromise.rejectedPromise` instead + /// + /// Create a new rejected promise without notifying the VM. Unhandled + /// rejections created this way will not trigger unhandled rejection handling. + pub fn dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis: *JSGlobalObject, value: JSValue) JSValue { return JSC__JSPromise__rejectedPromiseValue(globalThis, value); } @@ -280,8 +288,10 @@ pub const JSPromise = opaque { return JSC__JSPromise__create(globalThis); } + /// **DEPRECATED** use `JSPromise.toJS` instead pub fn asValue(this: *JSPromise, globalThis: *JSGlobalObject) JSValue { - return JSC__JSPromise__asValue(this, globalThis); + _ = globalThis; + return this.toJS(); } pub const Unwrapped = union(enum) { diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 627a1370d9..095799d1b5 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -5272,6 +5272,8 @@ void JSC__VM__throwError(JSC__VM* vm_, JSC__JSGlobalObject* arg1, JSC__JSValue e scope.throwException(arg1, exception); } +/// **DEPRECATED** This function does not notify the VM about the rejection, +/// meaning it will not trigger unhandled rejection handling. Use JSC__JSPromise__rejectedPromise instead. JSC__JSValue JSC__JSPromise__rejectedPromiseValue(JSC__JSGlobalObject* globalObject, JSC__JSValue JSValue1) { diff --git a/src/bun.js/node/node_fs_binding.zig b/src/bun.js/node/node_fs_binding.zig index feb633c2e0..2b05003f59 100644 --- a/src/bun.js/node/node_fs_binding.zig +++ b/src/bun.js/node/node_fs_binding.zig @@ -71,7 +71,7 @@ fn Bindings(comptime function_name: NodeFSFunctionEnum) type { const signal = args.signal orelse break :check_early_abort; if (signal.reasonIfAborted(globalObject)) |reason| { deinit = true; - return JSC.JSPromise.rejectedPromiseValue(globalObject, reason.toJS(globalObject)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalObject, reason.toJS(globalObject)); } } diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig index 161633fc62..bb530cbf62 100644 --- a/src/bun.js/webcore/blob.zig +++ b/src/bun.js/webcore/blob.zig @@ -947,14 +947,14 @@ pub const Blob = struct { } result.err = result.err.withPathLike(file.pathlike); - return JSC.JSPromise.rejectedPromiseValue(ctx, result.toJS(ctx)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, result.toJS(ctx)); } }, .s3 => |*s3| { // create empty file var aws_options = s3.getCredentialsWithOptions(options.extra_options, ctx) catch |err| { - return JSC.JSPromise.rejectedPromiseValue(ctx, ctx.takeException(err)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, ctx.takeException(err)); }; defer aws_options.deinit(); @@ -1073,7 +1073,7 @@ pub const Blob = struct { else if (destination_type == .file and source_type == .file) { if (comptime Environment.isWindows) { return Store.CopyFileWindows.init( - destination_blob.store.?, + destination_store, source_store, ctx.bunVM().eventLoop(), options.mkdirp_if_not_exists orelse true, @@ -1082,9 +1082,8 @@ pub const Blob = struct { } var file_copier = Store.CopyFile.create( bun.default_allocator, - destination_blob.store.?, + destination_store, source_store, - destination_blob.offset, destination_blob.size, ctx, @@ -1101,7 +1100,7 @@ pub const Blob = struct { ), ctx)) |stream| { return destination_blob.pipeReadableStreamToBlob(ctx, stream, options.extra_options); } else { - return JSC.JSPromise.rejectedPromiseValue(ctx, ctx.createErrorInstance("Failed to stream bytes from s3 bucket", .{})); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, ctx.createErrorInstance("Failed to stream bytes from s3 bucket", .{})); } } else if (destination_type == .bytes and source_type == .bytes) { // If this is bytes <> bytes, we can just duplicate it @@ -1121,9 +1120,9 @@ pub const Blob = struct { blob_value, ); } else if (destination_type == .s3) { - const s3 = &destination_blob.store.?.data.s3; + const s3 = &destination_store.data.s3; var aws_options = s3.getCredentialsWithOptions(options.extra_options, ctx) catch |err| { - return JSC.JSPromise.rejectedPromiseValue(ctx, ctx.takeException(err)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, ctx.takeException(err)); }; defer aws_options.deinit(); const proxy = ctx.bunVM().transpiler.env.getHttpProxy(true, null); @@ -1150,7 +1149,7 @@ pub const Blob = struct { undefined, ); } else { - return JSC.JSPromise.rejectedPromiseValue(ctx, ctx.createErrorInstance("Failed to stream bytes to s3 bucket", .{})); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, ctx.createErrorInstance("Failed to stream bytes to s3 bucket", .{})); } } else { const Wrapper = struct { @@ -1217,7 +1216,7 @@ pub const Blob = struct { undefined, ); } else { - return JSC.JSPromise.rejectedPromiseValue(ctx, ctx.createErrorInstance("Failed to stream bytes to s3 bucket", .{})); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, ctx.createErrorInstance("Failed to stream bytes to s3 bucket", .{})); } }, } @@ -1389,7 +1388,7 @@ pub const Blob = struct { .Error => |*err_ref| { destination_blob.detach(); _ = response.body.value.use(); - return JSC.JSPromise.rejectedPromiseValue(globalThis, err_ref.toJS(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err_ref.toJS(globalThis)); }, .Locked => |*locked| { if (destination_blob.isS3()) { @@ -1450,7 +1449,7 @@ pub const Blob = struct { .Error => |*err_ref| { destination_blob.detach(); _ = request.body.value.use(); - return JSC.JSPromise.rejectedPromiseValue(globalThis, err_ref.toJS(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err_ref.toJS(globalThis)); }, .Locked => |locked| { if (destination_blob.isS3()) { @@ -1598,7 +1597,7 @@ pub const Blob = struct { return .zero; } - return JSC.JSPromise.rejectedPromiseValue( + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, err.withPath(pathlike.path.slice()).toJSC(globalThis), ); @@ -1642,9 +1641,9 @@ pub const Blob = struct { return .zero; } if (comptime !needs_open) { - return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); } - return JSC.JSPromise.rejectedPromiseValue( + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, err.withPath(pathlike.path.slice()).toJSC(globalThis), ); @@ -1686,7 +1685,7 @@ pub const Blob = struct { } } - return JSC.JSPromise.rejectedPromiseValue( + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, err.withPath(pathlike.path.slice()).toJSC(globalThis), ); @@ -1723,12 +1722,12 @@ pub const Blob = struct { } } if (comptime !needs_open) { - return JSC.JSPromise.rejectedPromiseValue( + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, err.toJSC(globalThis), ); } - return JSC.JSPromise.rejectedPromiseValue( + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, err.withPath(pathlike.path.slice()).toJSC(globalThis), ); @@ -4302,13 +4301,13 @@ pub const Blob = struct { pub fn pipeReadableStreamToBlob(this: *Blob, globalThis: *JSC.JSGlobalObject, readable_stream: JSC.WebCore.ReadableStream, extra_options: ?JSValue) JSC.JSValue { var store = this.store orelse { - return JSC.JSPromise.rejectedPromiseValue(globalThis, globalThis.createErrorInstance("Blob is detached", .{})); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, globalThis.createErrorInstance("Blob is detached", .{})); }; if (this.isS3()) { const s3 = &this.store.?.data.s3; var aws_options = s3.getCredentialsWithOptions(extra_options, globalThis) catch |err| { - return JSC.JSPromise.rejectedPromiseValue(globalThis, globalThis.takeException(err)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, globalThis.takeException(err)); }; defer aws_options.deinit(); @@ -4332,7 +4331,7 @@ pub const Blob = struct { } if (store.data != .file) { - return JSC.JSPromise.rejectedPromiseValue(globalThis, globalThis.createErrorInstance("Blob is read-only", .{})); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, globalThis.createErrorInstance("Blob is read-only", .{})); } const file_sink = brk_sink: { @@ -4350,7 +4349,7 @@ pub const Blob = struct { break :brk result; }, .err => |err| { - return JSC.JSPromise.rejectedPromiseValue(globalThis, err.withPath(path).toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.withPath(path).toJSC(globalThis)); }, } unreachable; @@ -4383,7 +4382,7 @@ pub const Blob = struct { switch (sink.writer.startSync(fd, false)) { .err => |err| { sink.deref(); - return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); }, else => {}, } @@ -4391,7 +4390,7 @@ pub const Blob = struct { switch (sink.writer.start(fd, true)) { .err => |err| { sink.deref(); - return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); }, else => {}, } @@ -4426,7 +4425,7 @@ pub const Blob = struct { switch (sink.start(stream_start)) { .err => |err| { sink.deref(); - return JSC.JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); }, else => {}, } @@ -4455,7 +4454,7 @@ pub const Blob = struct { if (assignment_result.toError()) |err| { file_sink.deref(); - return JSC.JSPromise.rejectedPromiseValue(globalThis, err); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); } if (!assignment_result.isEmptyOrUndefinedOrNull()) { @@ -4491,7 +4490,7 @@ pub const Blob = struct { readable_stream.cancel(globalThis); - return JSC.JSPromise.rejectedPromiseValue(globalThis, promise.result(globalThis.vm())); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, promise.result(globalThis.vm())); }, } } else { @@ -4499,7 +4498,7 @@ pub const Blob = struct { readable_stream.cancel(globalThis); - return JSC.JSPromise.rejectedPromiseValue(globalThis, assignment_result); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, assignment_result); } } file_sink.deref(); diff --git a/src/bun.js/webcore/fetch.zig b/src/bun.js/webcore/fetch.zig index a6fbb26883..a81a2d2221 100644 --- a/src/bun.js/webcore/fetch.zig +++ b/src/bun.js/webcore/fetch.zig @@ -1426,7 +1426,7 @@ fn dataURLResponse( const data = data_url.decodeData(allocator) catch { const err = JSC.createError(globalThis, "failed to fetch the data URL", .{}); - return JSPromise.rejectedPromiseValue(globalThis, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); }; var blob = Blob.init(data, allocator, globalThis); @@ -1546,7 +1546,7 @@ pub fn Bun__fetch_( if (arguments.len == 0) { const err = JSC.toTypeError(.ERR_MISSING_ARGS, fetch_error_no_args, .{}, ctx); - return JSPromise.rejectedPromiseValue(globalThis, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); } var headers: ?Headers = null; @@ -1690,7 +1690,7 @@ pub fn Bun__fetch_( if (url_str.isEmpty()) { is_error = true; const err = JSC.toTypeError(.ERR_INVALID_URL, fetch_error_blank_url, .{}, ctx); - return JSPromise.rejectedPromiseValue(globalThis, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); } if (url_str.hasPrefixComptime("data:")) { @@ -1700,7 +1700,7 @@ pub fn Bun__fetch_( var data_url = DataURL.parseWithoutCheck(url_slice.slice()) catch { const err = JSC.createError(globalThis, "failed to fetch the data URL", .{}); is_error = true; - return JSPromise.rejectedPromiseValue(globalThis, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); }; data_url.url = url_str; @@ -1710,7 +1710,7 @@ pub fn Bun__fetch_( url = ZigURL.fromString(allocator, url_str) catch { const err = JSC.toTypeError(.ERR_INVALID_URL, "fetch() URL is invalid", .{}, ctx); is_error = true; - return JSPromise.rejectedPromiseValue( + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, err, ); @@ -1728,7 +1728,7 @@ pub fn Bun__fetch_( var data_url = DataURL.parseWithoutCheck(url_slice.slice()) catch { const err = JSC.createError(globalThis, "failed to fetch the data URL", .{}); - return JSPromise.rejectedPromiseValue(globalThis, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); }; data_url.url = url_str; @@ -2009,7 +2009,7 @@ pub fn Bun__fetch_( if (href.tag == .Dead) { const err = JSC.toTypeError(.ERR_INVALID_ARG_VALUE, "fetch() proxy URL is invalid", .{}, ctx); is_error = true; - return JSPromise.rejectedPromiseValue(globalThis, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); } defer href.deref(); const buffer = try std.fmt.allocPrint(allocator, "{s}{}", .{ url_proxy_buffer, href }); @@ -2248,7 +2248,7 @@ pub fn Bun__fetch_( if (proxy != null and unix_socket_path.length() > 0) { is_error = true; const err = JSC.toTypeError(.ERR_INVALID_ARG_VALUE, fetch_error_proxy_unix, .{}, ctx); - return JSPromise.rejectedPromiseValue(globalThis, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); } if (globalThis.hasException()) { @@ -2292,7 +2292,7 @@ pub fn Bun__fetch_( url_path_decoded, }, ctx); is_error = true; - return JSPromise.rejectedPromiseValue(globalThis, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); } } @@ -2365,14 +2365,14 @@ pub fn Bun__fetch_( if (!(url.isHTTP() or url.isHTTPS() or url.isS3())) { const err = JSC.toTypeError(.ERR_INVALID_ARG_VALUE, "protocol must be http:, https: or s3:", .{}, ctx); is_error = true; - return JSPromise.rejectedPromiseValue(globalThis, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); } } if (!method.hasRequestBody() and body.hasBody()) { const err = JSC.toTypeError(.ERR_INVALID_ARG_VALUE, fetch_error_unexpected_body, .{}, ctx); is_error = true; - return JSPromise.rejectedPromiseValue(globalThis, err); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); } if (headers == null and body.hasBody() and body.hasContentTypeFromUser()) { @@ -2394,7 +2394,7 @@ pub fn Bun__fetch_( body = .{ .ReadableStream = JSC.WebCore.ReadableStream.Strong.init(stream, globalThis) }; break :prepare_body; } - const rejected_value = JSPromise.rejectedPromiseValue(globalThis, globalThis.createErrorInstance("Failed to start s3 stream", .{})); + const rejected_value = JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, globalThis.createErrorInstance("Failed to start s3 stream", .{})); body.detach(); return rejected_value; @@ -2409,7 +2409,7 @@ pub fn Bun__fetch_( const opened_fd = switch (opened_fd_res) { .err => |err| { - const rejected_value = JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis)); + const rejected_value = JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); is_error = true; return rejected_value; }, @@ -2481,7 +2481,7 @@ pub fn Bun__fetch_( switch (res) { .err => |err| { is_error = true; - const rejected_value = JSPromise.rejectedPromiseValue(globalThis, err.toJSC(globalThis)); + const rejected_value = JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); body.detach(); return rejected_value; @@ -2569,7 +2569,7 @@ pub fn Bun__fetch_( } }; if (method != .PUT and method != .POST) { - return JSC.JSPromise.rejectedPromiseValue(globalThis, globalThis.createErrorInstance("Only POST and PUT do support body when using S3", .{})); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, globalThis.createErrorInstance("Only POST and PUT do support body when using S3", .{})); } const promise = JSC.JSPromise.Strong.init(globalThis); @@ -2608,7 +2608,7 @@ pub fn Bun__fetch_( .method = method, }, false, null) catch |sign_err| { is_error = true; - return JSPromise.rejectedPromiseValue(globalThis, s3.getJSSignError(sign_err, globalThis)); + return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, s3.getJSSignError(sign_err, globalThis)); }; defer result.deinit(); if (proxy) |proxy_| { diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig index 08afe3b5ae..b8daddbe89 100644 --- a/src/bun.js/webcore/streams.zig +++ b/src/bun.js/webcore/streams.zig @@ -5346,7 +5346,7 @@ pub const ByteStream = struct { this.pending.result.deinit(); this.done = true; this.buffer.clearAndFree(); - return JSC.JSPromise.rejectedPromiseValue(globalThis, err); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err); } if (this.toAnyBlob()) |blob_| { diff --git a/src/codegen/generate-node-errors.ts b/src/codegen/generate-node-errors.ts index 801d5754b6..b776c857da 100644 --- a/src/codegen/generate-node-errors.ts +++ b/src/codegen/generate-node-errors.ts @@ -73,7 +73,11 @@ pub fn ErrorBuilder(comptime code: Error, comptime fmt: [:0]const u8, Args: type /// Turn this into a JSPromise that is already rejected. pub inline fn reject(this: @This()) JSC.JSValue { - return JSC.JSPromise.rejectedPromiseValue(this.globalThis, code.fmt(this.globalThis, fmt, this.args)); + if (comptime bun.FeatureFlags.breaking_changes_1_3) { + return JSC.JSPromise.rejectedPromise(this.globalThis, code.fmt(this.globalThis, fmt, this.args)).toJS(); + } else { + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(this.globalThis, code.fmt(this.globalThis, fmt, this.args)); + } } }; } diff --git a/src/s3/client.zig b/src/s3/client.zig index f735f93ade..daed56b55b 100644 --- a/src/s3/client.zig +++ b/src/s3/client.zig @@ -426,12 +426,12 @@ pub fn uploadStream( const proxy_url = (proxy orelse ""); if (readable_stream.isDisturbed(globalThis)) { - return JSC.JSPromise.rejectedPromiseValue(globalThis, bun.String.static("ReadableStream is already disturbed").toErrorInstance(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, bun.String.static("ReadableStream is already disturbed").toErrorInstance(globalThis)); } switch (readable_stream.ptr) { .Invalid => { - return JSC.JSPromise.rejectedPromiseValue(globalThis, bun.String.static("ReadableStream is invalid").toErrorInstance(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, bun.String.static("ReadableStream is invalid").toErrorInstance(globalThis)); }, inline .File, .Bytes => |stream| { if (stream.pending.result == .err) {