diff --git a/src/jsc/bindings/BunPlugin.cpp b/src/jsc/bindings/BunPlugin.cpp index f5526c59a00..6e15de7463e 100644 --- a/src/jsc/bindings/BunPlugin.cpp +++ b/src/jsc/bindings/BunPlugin.cpp @@ -306,8 +306,11 @@ static inline JSC::EncodedJSValue setupBunPlugin(JSC::JSGlobalObject* globalObje auto targetValue = obj->getIfPropertyExists(globalObject, Identifier::fromString(vm, "target"_s)); RETURN_IF_EXCEPTION(throwScope, {}); if (targetValue) { - if (auto* targetJSString = targetValue.toStringOrNull(globalObject)) { + auto* targetJSString = targetValue.toStringOrNull(globalObject); + RETURN_IF_EXCEPTION(throwScope, {}); + if (targetJSString) { String targetString = targetJSString->value(globalObject); + RETURN_IF_EXCEPTION(throwScope, {}); if (!(targetString == "node"_s || targetString == "bun"_s || targetString == "browser"_s)) { JSC::throwTypeError(globalObject, throwScope, "plugin target must be one of 'node', 'bun' or 'browser'"_s); return {}; diff --git a/test/js/bun/plugin/plugins.test.ts b/test/js/bun/plugin/plugins.test.ts index 1ccd453b224..ad9d5100b4a 100644 --- a/test/js/bun/plugin/plugins.test.ts +++ b/test/js/bun/plugin/plugins.test.ts @@ -1,6 +1,6 @@ /// import { plugin } from "bun"; -import { describe, expect, it } from "bun:test"; +import { describe, expect, it, jest } from "bun:test"; import { resolve } from "path"; declare global { @@ -366,6 +366,23 @@ describe("errors", () => { }).toThrow("plugin target must be one of 'node', 'bun' or 'browser'"); }); + it("handles a 'target' whose toString throws", () => { + const setup = jest.fn(); + const opts = { + setup, + target: { + toString() { + throw new Error("boom from target toString"); + }, + }, + }; + + expect(() => { + plugin(opts as any); + }).toThrow("boom from target toString"); + expect(setup).not.toHaveBeenCalled(); + }); + it("invalid loaders throw", () => { const invalidLoaders = ["blah", "blah2", "blah3", "blah4"]; const inputs = ["body { background: red; }", "

hi

", '{"hi": "there"}', "hi"];