@samitouri / QOS-React-2 / commits / 1e71df5399

Improve error logging for event handlers of React components.

This guards every auto-bound method and uses the name of the component and method as guard name.

Felix Kling committed Nov 8, 2013 at 16:53 UTC 1e71df5399e4c94511e587fa368e7c57a537dc91
3 files changed +95 -1
src/core/ReactCompositeComponent.js
+5 -1
@@ -20,6 +20,7 @@
20
21 var ReactComponent = require('ReactComponent');
22 var ReactCurrentOwner = require('ReactCurrentOwner');
23 +var ReactErrorUtils = require('ReactErrorUtils');
24 var ReactOwner = require('ReactOwner');
25 var ReactPerf = require('ReactPerf');
26 var ReactPropTransferer = require('ReactPropTransferer');
@@ -877,7 +878,10 @@ var ReactCompositeComponentMixin = {
878 continue;
879 }
880 var method = this.__reactAutoBindMap[autoBindKey];
880 - this[autoBindKey] = this._bindAutoBindMethod(method);
881 + this[autoBindKey] = ReactErrorUtils.guard(
882 + this._bindAutoBindMethod(method),
883 + this.constructor.displayName + '.' + autoBindKey
884 + );
885 }
886 },
887
src/core/__tests__/ReactCompositeComponentError-test.js new
+46
@@ -0,0 +1,46 @@
1 +/**
2 + * Copyright 2013 Facebook, Inc.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + *
16 + * @jsx React.DOM
17 + * @emails react-core
18 + */
19 +
20 +"use strict";
21 +
22 +var React = require('React');
23 +var ReactTestUtils = require('ReactTestUtils');
24 +var ReactErrorUtils;
25 +
26 +describe('ReactCompositeComponent-error', function() {
27 +
28 + beforeEach(function() {
29 + ReactErrorUtils = require('ReactErrorUtils');
30 + });
31 +
32 + it('should be passed the component and method name', function() {
33 + var Component = React.createClass({
34 + someHandler: function() {},
35 + render: function() {
36 + return <div />;
37 + }
38 + });
39 +
40 + var instance = <Component />;
41 + ReactTestUtils.renderIntoDocument(instance);
42 + expect(ReactErrorUtils.guard.mock.calls[0][1])
43 + .toEqual('Component.someHandler');
44 + });
45 +
46 +});
src/vendor/stubs/ReactErrorUtils.js new
+44
@@ -0,0 +1,44 @@
1 +/**
2 + * Copyright 2013 Facebook, Inc.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + *
16 + * @providesModule ReactErrorUtils
17 + * @typechecks
18 + */
19 +
20 +var ReactErrorUtils = {
21 + /**
22 + * Creates a guarded version of a function. This is supposed to make debugging
23 + * of event handlers easier. This implementation provides only basic error
24 + * logging and re-throws the error.
25 + *
26 + * @param {function} func Function to be executed
27 + * @param {string} name The name of the guard
28 + * @return {function}
29 + */
30 + guard: function(func, name) {
31 + return function guarded() {
32 + try {
33 + return func.apply(this, arguments);
34 + } catch(ex) {
35 + if (__DEV__) {
36 + console.error(name + ': ' + ex.message);
37 + }
38 + throw ex;
39 + }
40 + };
41 + }
42 +};
43 +
44 +module.exports = ReactErrorUtils;