mirror of
https://github.com/oven-sh/bun
synced 2026-02-13 04:18:58 +00:00
Fix some errors not showing up in GitHub annotations (#8799)
* Remove dead code now that `expect()` can be used outside of tests * Fix some errors not being rendered to GitHub annotations * [autofix.ci] apply automated fixes * Update jest.zig Try `execCallback` --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -579,8 +579,6 @@ pub const VirtualMachine = struct {
|
||||
onUnhandledRejectionCtx: ?*anyopaque = null,
|
||||
unhandled_error_counter: usize = 0,
|
||||
|
||||
on_exception: ?*const OnException = null,
|
||||
|
||||
modules: ModuleLoader.AsyncModule.Queue = .{},
|
||||
aggressive_garbage_collection: GCLevel = GCLevel.none,
|
||||
|
||||
@@ -626,14 +624,6 @@ pub const VirtualMachine = struct {
|
||||
return this.debugger != null;
|
||||
}
|
||||
|
||||
pub fn setOnException(this: *VirtualMachine, callback: *const OnException) void {
|
||||
this.on_exception = callback;
|
||||
}
|
||||
|
||||
pub fn clearOnException(this: *VirtualMachine) void {
|
||||
this.on_exception = null;
|
||||
}
|
||||
|
||||
const VMHolder = struct {
|
||||
pub threadlocal var vm: ?*VirtualMachine = null;
|
||||
};
|
||||
@@ -2771,10 +2761,8 @@ pub const VirtualMachine = struct {
|
||||
this.had_errors = true;
|
||||
defer this.had_errors = prev_had_errors;
|
||||
|
||||
if (allow_side_effects) {
|
||||
defer if (this.on_exception) |cb| {
|
||||
cb(exception);
|
||||
};
|
||||
if (allow_side_effects and Output.is_github_action) {
|
||||
defer printGithubAnnotation(exception);
|
||||
}
|
||||
|
||||
const line_numbers = exception.stack.source_lines_numbers[0..exception.stack.source_lines_len];
|
||||
@@ -3007,6 +2995,127 @@ pub const VirtualMachine = struct {
|
||||
}
|
||||
}
|
||||
|
||||
// In Github Actions, emit an annotation that renders the error and location.
|
||||
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message
|
||||
pub fn printGithubAnnotation(exception: *JSC.ZigException) void {
|
||||
const name = exception.name;
|
||||
const message = exception.message;
|
||||
const frames = exception.stack.frames();
|
||||
const top_frame = if (frames.len > 0) frames[0] else null;
|
||||
const dir = bun.getenvZ("GITHUB_WORKSPACE") orelse bun.fs.FileSystem.instance.top_level_dir;
|
||||
const allocator = bun.default_allocator;
|
||||
|
||||
var has_location = false;
|
||||
|
||||
if (top_frame) |frame| {
|
||||
if (!frame.position.isInvalid()) {
|
||||
const source_url = frame.source_url.toUTF8(allocator);
|
||||
defer source_url.deinit();
|
||||
const file = bun.path.relative(dir, source_url.slice());
|
||||
Output.printError("\n::error file={s},line={d},col={d},title=", .{
|
||||
file,
|
||||
frame.position.line_start + 1,
|
||||
frame.position.column_start,
|
||||
});
|
||||
has_location = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_location) {
|
||||
Output.printError("\n::error title=", .{});
|
||||
}
|
||||
|
||||
if (name.isEmpty() or name.eqlComptime("Error")) {
|
||||
Output.printError("error", .{});
|
||||
} else {
|
||||
Output.printError("{s}", .{name.githubAction()});
|
||||
}
|
||||
|
||||
if (!message.isEmpty()) {
|
||||
const message_slice = message.toUTF8(allocator);
|
||||
defer message_slice.deinit();
|
||||
const msg = message_slice.slice();
|
||||
|
||||
var cursor: u32 = 0;
|
||||
while (strings.indexOfNewlineOrNonASCIIOrANSI(msg, cursor)) |i| {
|
||||
cursor = i + 1;
|
||||
if (msg[i] == '\n') {
|
||||
const first_line = bun.String.fromUTF8(msg[0..i]);
|
||||
Output.printError(": {s}::", .{first_line.githubAction()});
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
Output.printError(": {s}::", .{message.githubAction()});
|
||||
}
|
||||
|
||||
while (strings.indexOfNewlineOrNonASCIIOrANSI(msg, cursor)) |i| {
|
||||
cursor = i + 1;
|
||||
if (msg[i] == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor > 0) {
|
||||
const body = ZigString.init(msg[cursor..]);
|
||||
Output.printError("{s}", .{body.githubAction()});
|
||||
}
|
||||
} else {
|
||||
Output.printError("::", .{});
|
||||
}
|
||||
|
||||
// TODO: cleanup and refactor to use printStackTrace()
|
||||
if (top_frame) |_| {
|
||||
const vm = VirtualMachine.get();
|
||||
const origin = if (vm.is_from_devserver) &vm.origin else null;
|
||||
|
||||
var i: i16 = 0;
|
||||
while (i < frames.len) : (i += 1) {
|
||||
const frame = frames[@as(usize, @intCast(i))];
|
||||
const source_url = frame.source_url.toUTF8(allocator);
|
||||
defer source_url.deinit();
|
||||
const file = bun.path.relative(dir, source_url.slice());
|
||||
const func = frame.function_name.toUTF8(allocator);
|
||||
|
||||
if (file.len == 0 and func.len == 0) continue;
|
||||
|
||||
const has_name = std.fmt.count("{any}", .{frame.nameFormatter(
|
||||
false,
|
||||
)}) > 0;
|
||||
|
||||
// %0A = escaped newline
|
||||
if (has_name) {
|
||||
Output.printError(
|
||||
"%0A at {any} ({any})",
|
||||
.{
|
||||
frame.nameFormatter(false),
|
||||
frame.sourceURLFormatter(
|
||||
file,
|
||||
origin,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
Output.printError(
|
||||
"%0A at {any}",
|
||||
.{
|
||||
frame.sourceURLFormatter(
|
||||
file,
|
||||
origin,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Output.printError("\n", .{});
|
||||
Output.flush();
|
||||
}
|
||||
|
||||
extern fn Process__emitMessageEvent(global: *JSGlobalObject, value: JSValue) void;
|
||||
extern fn Process__emitDisconnectEvent(global: *JSGlobalObject) void;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user