boa icon indicating copy to clipboard operation
boa copied to clipboard

to_json() on a nested data structure containing undefined should not fail

Open gschier opened this issue 1 year ago • 3 comments

Describe the bug

When calling to_json on an object like {foo: undefined}, it should result in {} and not panic. Here are some various behaviors (demo's using Node) which it would be good to follow:

> JSON.stringify({foo: undefined, bar: 1})
'{"bar":1}'
> JSON.stringify(undefined)
undefined
> JSON.stringify([1,2,undefined,4])
'[1,2,null,4]'

For context, I'm building a 3rd-party plugin system for Yaak using Boa and users may return a nested data structure that contain undefined values.

To Reproduce

Return an object from the JS context and call to_json on it.

export function callMe() {
  return { foo: undefined };
}

Expected behavior

The value should serialize to {} and not throw not yet implemented: undefined to JSON.

Build environment (please complete the following information):

  • OS: macOS
  • Version: 14
  • Target triple: aarch64-apple-darwin
  • Rustc version: rustc 1.77.2 (25ef9e3d8 2024-04-09)

Additional context

The current workaround is to return JSON.parse(JSON.stringify(objectContainingUndefineds)). However, as I'm using Boa to build a plugin system, I wouldn't expect users to have to do this themselves.

Another potential workaround is to recursively crawl the JSValue and remove undefined values from all the objects and arrays.

Thanks for taking the time to look into this!

gschier avatar May 08 '24 02:05 gschier

I think the confusion here is that the to_json and from_json methods are misnomers; those functions just try to convert from serde_json's Value to Boa's JsValue, and since serde_json does not support "undefined", we cannot convert to it.

The solution here would be to expose JSON::stringify and JSON::parse as Rust APIs, and rename the serde_json APIs to to_serde_json_value and from_serde_json_value.

jedel1043 avatar Jun 01 '24 18:06 jedel1043

@gschier I'm not sure if I get it right, are you tying to call to_json in rust side with a JSValue::Object contains undefined and result in an error shows not yet implemented: undefined to JSON? As @jedel1043 explained, serde_json dose not allow convert value to undefined.

So what behavior is it expected to be?

Fnll avatar Jun 18 '24 03:06 Fnll

I think what serde_json is doing is a Serde-specific implementation. boa should follow the spec and return {}.

Taym95 avatar Aug 29 '24 14:08 Taym95

I've created PR #4212 which I think handles undefined in a sensible way. Comments welcome.

jamesthurley avatar Mar 20 '25 15:03 jamesthurley

Thanks for taking care of this!

gschier avatar Mar 21 '25 03:03 gschier