@@ -3398,8 +3398,8 @@ const TaggedAnyOpaque = struct {
33983398
33993399fn valueToDetailString (arena : Allocator , value : v8.Value , isolate : v8.Isolate , v8_context : v8.Context ) ! []u8 {
34003400 var str : ? v8.String = null ;
3401- if (value .isObject () and ! value .isFunction ()) {
3402- str = try v8 .Json .stringify (v8_context , value , null );
3401+ if (value .isObject () and ! value .isFunction ()) blk : {
3402+ str = v8 .Json .stringify (v8_context , value , null ) catch break : blk ;
34033403
34043404 if (str .? .lenUtf8 (isolate ) == 2 ) {
34053405 // {} isn't useful, null this so that we can get the toDetailString
@@ -3412,10 +3412,24 @@ fn valueToDetailString(arena: Allocator, value: v8.Value, isolate: v8.Isolate, v
34123412 str = try value .toDetailString (v8_context );
34133413 }
34143414
3415- return jsStringToZig (arena , str .? , isolate );
3415+ const s = try jsStringToZig (arena , str .? , isolate );
3416+ if (comptime builtin .mode == .Debug ) {
3417+ if (std .mem .eql (u8 , s , "[object Object]" )) {
3418+ if (debugValueToString (arena , value .castTo (v8 .Object ), isolate , v8_context )) | ds | {
3419+ return ds ;
3420+ } else | err | {
3421+ log .err (.js , "debug serialize value" , .{.err = err });
3422+ }
3423+ }
3424+ }
3425+ return s ;
34163426}
34173427
34183428fn valueToString (allocator : Allocator , value : v8.Value , isolate : v8.Isolate , v8_context : v8.Context ) ! []u8 {
3429+ if (value .isSymbol ()) {
3430+ // symbol's can't be converted to a string
3431+ return allocator .dupe (u8 , "$Symbol" );
3432+ }
34193433 const str = try value .toString (v8_context );
34203434 return jsStringToZig (allocator , str , isolate );
34213435}
@@ -3437,6 +3451,38 @@ fn jsStringToZig(allocator: Allocator, str: v8.String, isolate: v8.Isolate) ![]u
34373451 return buf ;
34383452}
34393453
3454+ fn debugValueToString (arena : Allocator , js_obj : v8.Object , isolate : v8.Isolate , v8_context : v8.Context ) ! []u8 {
3455+ if (comptime builtin .mode != .Debug ) {
3456+ @compileError ("debugValue can only be called in debug mode" );
3457+ }
3458+
3459+ var arr : std .ArrayListUnmanaged (u8 ) = .empty ;
3460+ var writer = arr .writer (arena );
3461+
3462+ const names_arr = js_obj .getOwnPropertyNames (v8_context );
3463+ const names_obj = names_arr .castTo (v8 .Object );
3464+ const len = names_arr .length ();
3465+
3466+ try writer .writeAll ("(JSON.stringify failed, dumping top-level fields)\n " );
3467+ for (0.. len ) | i | {
3468+ const field_name = try names_obj .getAtIndex (v8_context , @intCast (i ));
3469+ const field_value = try js_obj .getValue (v8_context , field_name );
3470+ const name = try valueToString (arena , field_name , isolate , v8_context );
3471+ const value = try valueToString (arena , field_value , isolate , v8_context );
3472+ try writer .writeAll (name );
3473+ try writer .writeAll (": " );
3474+ if (std .mem .indexOfAny (u8 , value , & std .ascii .whitespace ) == null ) {
3475+ try writer .writeAll (value );
3476+ } else {
3477+ try writer .writeByte ('"' );
3478+ try writer .writeAll (value );
3479+ try writer .writeByte ('"' );
3480+ }
3481+ try writer .writeByte (' ' );
3482+ }
3483+ return arr .items ;
3484+ }
3485+
34403486fn stackForLogs (arena : Allocator , isolate : v8.Isolate ) ! ? []const u8 {
34413487 std .debug .assert (builtin .mode == .Debug );
34423488
0 commit comments