Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPLAT-10894 Rethrow and print registerComponent/registerComponent2 errors #261

Merged
merged 2 commits into from Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 27 additions & 3 deletions lib/react_client.dart
Expand Up @@ -629,6 +629,7 @@ ReactDartComponentFactoryProxy _registerComponent(
ComponentFactory componentFactory, [ ComponentFactory componentFactory, [
Iterable<String> skipMethods = const ['getDerivedStateFromError', 'componentDidCatch'], Iterable<String> skipMethods = const ['getDerivedStateFromError', 'componentDidCatch'],
]) { ]) {
try {
var componentInstance = componentFactory(); var componentInstance = componentFactory();


if (componentInstance is Component2) { if (componentInstance is Component2) {
Expand All @@ -655,6 +656,10 @@ ReactDartComponentFactoryProxy _registerComponent(
reactComponentClass.dartDefaultProps = defaultProps; reactComponentClass.dartDefaultProps = defaultProps;


return new ReactDartComponentFactoryProxy(reactComponentClass); return new ReactDartComponentFactoryProxy(reactComponentClass);
} catch (e, stack) {
print('Error when registering Component: $e\n$stack');
rethrow;
}
} }


/// Creates ReactJS [ReactElement] instances for `JSContext` components. /// Creates ReactJS [ReactElement] instances for `JSContext` components.
Expand Down Expand Up @@ -775,6 +780,8 @@ ReactDartComponentFactoryProxy2 _registerComponent2(
Iterable<String> skipMethods = const ['getDerivedStateFromError', 'componentDidCatch'], Iterable<String> skipMethods = const ['getDerivedStateFromError', 'componentDidCatch'],
Component2BridgeFactory bridgeFactory, Component2BridgeFactory bridgeFactory,
}) { }) {
bool errorPrinted = false;
try {
bridgeFactory ??= Component2BridgeImpl.bridgeFactory; bridgeFactory ??= Component2BridgeImpl.bridgeFactory;


final componentInstance = componentFactory(); final componentInstance = componentFactory();
Expand All @@ -787,10 +794,23 @@ ReactDartComponentFactoryProxy2 _registerComponent2(


// Cache default props and store them on the ReactClass so they can be used // Cache default props and store them on the ReactClass so they can be used
// by ReactDartComponentFactoryProxy and externally. // by ReactDartComponentFactoryProxy and externally.
final JsBackedMap defaultProps = new JsBackedMap.from(componentInstance.defaultProps); JsBackedMap defaultProps;
try {
defaultProps = JsBackedMap.from(componentInstance.defaultProps);
} catch (e, stack) {
print('Error when registering Component2 when getting defaultProps: $e\n$stack');
errorPrinted = true;
rethrow;
}


final JsMap jsPropTypes = JsMap jsPropTypes;
bridgeFactory(componentInstance).jsifyPropTypes(componentInstance, componentInstance.propTypes); try {
jsPropTypes = bridgeFactory(componentInstance).jsifyPropTypes(componentInstance, componentInstance.propTypes);
} catch (e, stack) {
print('Error when registering Component2 when getting propTypes: $e\n$stack');
errorPrinted = true;
rethrow;
}


var jsConfig2 = new JsComponentConfig2( var jsConfig2 = new JsComponentConfig2(
defaultProps: defaultProps.jsObject, defaultProps: defaultProps.jsObject,
Expand All @@ -808,6 +828,10 @@ ReactDartComponentFactoryProxy2 _registerComponent2(
reactComponentClass.dartComponentVersion = ReactDartComponentVersion.component2; reactComponentClass.dartComponentVersion = ReactDartComponentVersion.component2;


return new ReactDartComponentFactoryProxy2(reactComponentClass); return new ReactDartComponentFactoryProxy2(reactComponentClass);
} catch (e, stack) {
if (!errorPrinted) print('Error when registering Component2: $e\n$stack');
rethrow;
}
} }


/// Creates ReactJS [ReactElement] instances for DOM components. /// Creates ReactJS [ReactElement] instances for DOM components.
Expand Down
68 changes: 68 additions & 0 deletions test/react_client_test.dart
Expand Up @@ -173,6 +173,46 @@ main() {
expect(result, isNull); expect(result, isNull);
}); });
}); });

group('registerComponent', () {
test('throws with printed error', () {
expect(() => react.registerComponent(() => ThrowsInDefaultPropsComponent()), throwsStateError);
expect(() {
try {
react.registerComponent(() => ThrowsInDefaultPropsComponent());
} catch (_) {}
}, prints(contains('Error when registering Component:')));
});
});

group('registerComponent2', () {
test('throws with specific error when defaultProps throws', () {
expect(() => react.registerComponent2(() => ThrowsInDefaultPropsComponent2()), throwsStateError);
expect(() {
try {
react.registerComponent2(() => ThrowsInDefaultPropsComponent2());
} catch (_) {}
}, prints(contains('Error when registering Component2 when getting defaultProps')));
});

test('throws with specific error when propTypes throws', () {
expect(() => react.registerComponent2(() => ThrowsInPropTypesComponent2()), throwsStateError);
expect(() {
try {
react.registerComponent2(() => ThrowsInPropTypesComponent2());
} catch (_) {}
}, prints(contains('Error when registering Component2 when getting propTypes')));
});

test('throws with generic error when something else throws', () {
expect(() => react.registerComponent2(() => throw StateError('bad component')), throwsStateError);
expect(() {
try {
react.registerComponent2(() => throw StateError('bad component'));
} catch (_) {}
}, prints(contains('Error when registering Component2:')));
});
});
} }


@JS() @JS()
Expand All @@ -187,6 +227,34 @@ final Function testJsComponentFactory = (() {
}; };
})(); })();


class ThrowsInDefaultPropsComponent extends Component {
@override
Map getDefaultProps() => throw StateError('bad default props');

@override
render() {
return null;
}
}

class ThrowsInDefaultPropsComponent2 extends Component2 {
get defaultProps => throw StateError('bad default props');

@override
render() {
return null;
}
}

class ThrowsInPropTypesComponent2 extends Component2 {
get propTypes => throw StateError('bad prop types');

@override
render() {
return null;
}
}

class DartComponent2Component extends Component2 { class DartComponent2Component extends Component2 {
@override @override
render() { render() {
Expand Down