Compare commits

...

2 Commits

Author SHA1 Message Date
Jarred Sumner
cd264c26cc Fixes #10170 2024-05-20 18:43:40 -07:00
Jarred Sumner
53b3c13e1a Always propagate error 2024-05-20 18:40:31 -07:00
4 changed files with 57 additions and 8 deletions

View File

@@ -183,8 +183,18 @@ void EventEmitter::fireEventListeners(const Identifier& eventType, const MarkedA
return;
auto* listenersVector = data->eventListenerMap.find(eventType);
if (UNLIKELY(!listenersVector))
if (UNLIKELY(!listenersVector)) {
if (eventType == scriptExecutionContext()->vm().propertyNames->error && arguments.size() > 0) {
Ref<EventEmitter> protectedThis(*this);
auto* thisObject = protectedThis->m_thisObject.get();
if (!thisObject)
return;
Bun__reportUnhandledError(thisObject->globalObject(), JSValue::encode(arguments.at(0)));
return;
}
return;
}
bool prevFiringEventListeners = data->isFiringEventListeners;
data->isFiringEventListeners = true;
@@ -207,6 +217,11 @@ void EventEmitter::innerInvokeEventListeners(const Identifier& eventType, Simple
auto* thisObject = protectedThis->m_thisObject.get();
JSC::JSValue thisValue = thisObject ? JSC::JSValue(thisObject) : JSC::jsUndefined();
if (UNLIKELY(listeners.isEmpty() && eventType == vm.propertyNames->error) && arguments.size() > 0) {
Bun__reportUnhandledError(thisObject->globalObject(), JSValue::encode(arguments.at(0)));
return;
}
for (auto& registeredListener : listeners) {
if (UNLIKELY(registeredListener->wasRemoved()))
continue;

View File

@@ -456,14 +456,11 @@ function exec(command, options, callback) {
return execFile(opts.file, opts.options, opts.callback);
}
const kCustomPromisifySymbol = Symbol.for("nodejs.util.promisify.custom");
const customPromiseExecFunction = orig => {
return (...args) => {
let resolve;
let reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
const { resolve, reject, promise } = Promise.withResolvers();
promise.child = orig(...args, (err, stdout, stderr) => {
if (err !== null) {
@@ -479,12 +476,22 @@ const customPromiseExecFunction = orig => {
};
};
Object.defineProperty(exec, Symbol.for("nodejs.util.promisify.custom"), {
Object.defineProperty(exec, kCustomPromisifySymbol, {
__proto__: null,
configurable: true,
value: customPromiseExecFunction(exec),
});
exec[kCustomPromisifySymbol][kCustomPromisifySymbol] = exec[kCustomPromisifySymbol];
Object.defineProperty(execFile, kCustomPromisifySymbol, {
__proto__: null,
configurable: true,
value: customPromiseExecFunction(execFile),
});
execFile[kCustomPromisifySymbol][kCustomPromisifySymbol] = execFile[kCustomPromisifySymbol];
/**
* Spawns a new process synchronously using the given `file`.
* @param {string} file

View File

@@ -598,3 +598,19 @@ it("emits newListener event _before_ adding the listener", () => {
stream.on("foo", () => {});
expect(cb).toHaveBeenCalled();
});
it("reports error", () => {
expect(() => {
const dup = new Duplex({
read() {
this.push("Hello World!\n");
this.push(null);
},
write(chunk, encoding, callback) {
callback(new Error("test"));
},
});
dup.emit("error", new Error("test"));
}).toThrow("test");
});

View File

@@ -0,0 +1,11 @@
import { test, expect } from "bun:test";
import { bunExe } from "harness";
import { execFile } from "node:child_process";
import util from "node:util";
test("issue 10170", async () => {
const execFileAsync = util.promisify(execFile);
const result = await execFileAsync(bunExe(), ["--version"]);
expect(result.stdout).toContain(Bun.version);
expect(result.stderr).toBe("");
});