- segfault reading stacktrace from `fs/promises` rejections
- `Promise` rejection within `describe()` ends testing abruptly
- `FSSink.write()` incorrectly handles `objectMode`
- `FSSink.write()` throws wrong error codes
This commit is contained in:
Alex Lam S.L
2023-01-15 02:50:55 +02:00
committed by GitHub
parent d01ec47529
commit 136014b13a
4 changed files with 54 additions and 22 deletions

View File

@@ -1848,8 +1848,11 @@ pub const VirtualMachine = struct {
const message = exception.message;
var did_print_name = false;
if (source_lines.next()) |source| {
if (source.text.len > 0 and exception.stack.frames()[0].position.isInvalid()) {
if (source_lines.next()) |source| brk: {
if (source.text.len == 0) break :brk;
const top_frame = if (exception.stack.frames_len > 0) exception.stack.frames()[0] else null;
if (top_frame == null or top_frame.?.position.isInvalid()) {
defer did_print_name = true;
var text = std.mem.trim(u8, source.text, "\n");
@@ -1864,12 +1867,11 @@ pub const VirtualMachine = struct {
);
try this.printErrorNameAndMessage(name, message, Writer, writer, allow_ansi_color);
} else if (source.text.len > 0) {
} else if (top_frame) |top| {
defer did_print_name = true;
const int_size = std.fmt.count("{d}", .{source.line});
const pad = max_line_number_pad - int_size;
try writer.writeByteNTimes(' ', pad);
const top = exception.stack.frames()[0];
var remainder = std.mem.trim(u8, source.text, "\n");
try writer.print(

View File

@@ -2028,14 +2028,13 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type {
const args_list = callframe.arguments(4);
const args = args_list.ptr[0..args_list.len];
if (args.len == 0 or args[0].isEmptyOrUndefinedOrNull() or args[0].isNumber()) {
const err = JSC.toTypeError(
if (args.len == 0) JSC.Node.ErrorCode.ERR_MISSING_ARGS else JSC.Node.ErrorCode.ERR_INVALID_ARG_TYPE,
if (args.len == 0) {
globalThis.vm().throwError(globalThis, JSC.toTypeError(
JSC.Node.ErrorCode.ERR_MISSING_ARGS,
"write() expects a string, ArrayBufferView, or ArrayBuffer",
.{},
globalThis,
);
globalThis.vm().throwError(globalThis, err);
));
return JSC.JSValue.jsUndefined();
}
@@ -2043,6 +2042,16 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type {
arg.ensureStillAlive();
defer arg.ensureStillAlive();
if (arg.isEmptyOrUndefinedOrNull()) {
globalThis.vm().throwError(globalThis, JSC.toTypeError(
JSC.Node.ErrorCode.ERR_STREAM_NULL_VALUES,
"write() expects a string, ArrayBufferView, or ArrayBuffer",
.{},
globalThis,
));
return JSC.JSValue.jsUndefined();
}
if (arg.asArrayBuffer(globalThis)) |buffer| {
const slice = buffer.slice();
if (slice.len == 0) {
@@ -2052,6 +2061,16 @@ pub fn NewJSSink(comptime SinkType: type, comptime name_: []const u8) type {
return this.sink.writeBytes(.{ .temporary = bun.ByteList.init(slice) }).toJS(globalThis);
}
if (!arg.isString()) {
globalThis.vm().throwError(globalThis, JSC.toTypeError(
JSC.Node.ErrorCode.ERR_INVALID_ARG_TYPE,
"write() expects a string, ArrayBufferView, or ArrayBuffer",
.{},
globalThis,
));
return JSC.JSValue.jsUndefined();
}
const str = arg.getZigString(globalThis);
if (str.len == 0) {
return JSC.JSValue.jsNumber(0);

View File

@@ -478,7 +478,7 @@ pub const TestCommand = struct {
if (reporter.summary.expectations > 0) Output.prettyError(" {d:5>} expect() calls\n", .{reporter.summary.expectations});
Output.prettyError(
\\ Ran {d} tests across {d} files
\\ Ran {d} tests across {d} files
, .{
reporter.summary.fail + reporter.summary.pass,
test_files.len,
@@ -593,8 +593,8 @@ pub const TestCommand = struct {
module.runTests(JSC.JSValue.zero, vm.global);
vm.eventLoop().tick();
const initial_unhandled_counter = vm.unhandled_error_counter;
while (vm.active_tasks > 0 and vm.unhandled_error_counter == initial_unhandled_counter) {
var prev_unhandled_count = vm.unhandled_error_counter;
while (vm.active_tasks > 0) {
if (!jest.Jest.runner.?.has_pending_tests) jest.Jest.runner.?.drain();
vm.eventLoop().tick();
@@ -603,6 +603,11 @@ pub const TestCommand = struct {
if (!jest.Jest.runner.?.has_pending_tests) break;
vm.eventLoop().tick();
}
while (prev_unhandled_count < vm.unhandled_error_counter) {
vm.global.handleRejectedPromises();
prev_unhandled_count = vm.unhandled_error_counter;
}
}
_ = vm.global.vm().runGC(false);
}

View File

@@ -500,20 +500,20 @@ describe("createWriteStream", () => {
const stream = createWriteStream(path);
try {
stream.write(null);
throw new Error("should not get here");
expect(() => {}).toThrow(Error);
} catch (exception) {
expect(exception.code).toBe("ERR_STREAM_NULL_VALUES");
}
});
it("writing null with objectMode: true throws ERR_STREAM_NULL_VALUES", async () => {
it("writing null throws ERR_STREAM_NULL_VALUES (objectMode: true)", async () => {
const path = `/tmp/fs.test.js/${Date.now()}.createWriteStreamNulls.txt`;
const stream = createWriteStream(path, {
objectMode: true,
});
try {
stream.write(null);
throw new Error("should not get here");
expect(() => {}).toThrow(Error);
} catch (exception) {
expect(exception.code).toBe("ERR_STREAM_NULL_VALUES");
}
@@ -524,26 +524,32 @@ describe("createWriteStream", () => {
const stream = createWriteStream(path);
try {
stream.write(false);
throw new Error("should not get here");
expect(() => {}).toThrow(Error);
} catch (exception) {
expect(exception.code).toBe("ERR_INVALID_ARG_TYPE");
}
});
it("writing false with objectMode: true should not throw", async () => {
it("writing false throws ERR_INVALID_ARG_TYPE (objectMode: true)", async () => {
const path = `/tmp/fs.test.js/${Date.now()}.createWriteStreamFalse.txt`;
const stream = createWriteStream(path, {
objectMode: true,
});
stream.write(false);
stream.on("error", () => {
throw new Error("should not get here");
});
try {
stream.write(false);
expect(() => {}).toThrow(Error);
} catch (exception) {
expect(exception.code).toBe("ERR_INVALID_ARG_TYPE");
}
});
});
describe("fs/promises", () => {
const { readFile, writeFile } = promises;
const { readFile, stat, writeFile } = promises;
it("should not segfault on exception", async () => {
stat("foo/bar");
});
it("readFile", async () => {
const data = await readFile(import.meta.dir + "/readFileSync.txt", "utf8");