react-jsonschema-form
react-jsonschema-form copied to clipboard
Schema/UiSchema errors crash the Playground on React 16
Prerequisites
- [x] I have read the documentation;
- [x] In the case of a bug report, I understand that providing a SSCCE example is tremendously useful to the maintainers.
Description
When passing certain Schema or UiSchema documents as props, the Form component throws an exception on the render method. On the Playground, these are caught by a try/catch in the Editor component: https://github.com/mozilla-services/react-jsonschema-form/blob/e4378c2a0b738eeee151e82c4533d2a79b80346c/playground/app.js#L195-L199
This works because the setState call inside the try/catch and the render call happen inside the same event loop iteration. This has never been guaranteed to happen, and the behaviour changed in react 16.
Steps to Reproduce
- Compile the Playground on React 16
- Make
uiSchemareference a widget that doesn't exist
Expected behavior
Application works. Form goes into the invalid state. When the error is fixed, it goes back to normal. No unhandled exception is thrown.
Actual behavior
Application immediately crashes as an uncaught exception is thrown in Form.render().
Version
react-jsonschema-form: 1.0.2 react: 16.2.0 react-dom: 16.2.0
It wouldn't surprise me to discover that there were enormous problems with how we handle updating the state. For instance, see https://github.com/mozilla-services/react-jsonschema-form/issues/446. I don't know React well enough to try to clean this up, but patches would be welcome!
I think the original idear of "setImmediate", "safeRenderCompletion" stuff is "trying to catch exceptions thrown by getWidget".
I would highly recommend that "getWidget" should return a default widget, or similar to "UnsupportedField" for unsupported schema, return an "UiSchemaError" component to display error message in the form, instead of throwing an exception. So that those "setImmediate" "safeRenderCompletion" workaround can be removed.
Here is an official doc about Error Handling in React 16. I haven't tried but I think adding "componentDidCatch" into "SchemaField" should work and the outcome - ’display a “Something went wrong” message to the user‘ is the same as above.