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.
This commit is contained in:
Felix Kling
2013-11-11 16:39:25 -08:00
committed by Paul O’Shannessy
parent 48948c91c3
commit 1e71df5399
3 changed files with 95 additions and 1 deletions
+5 -1
View File
@@ -20,6 +20,7 @@
var ReactComponent = require('ReactComponent');
var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactErrorUtils = require('ReactErrorUtils');
var ReactOwner = require('ReactOwner');
var ReactPerf = require('ReactPerf');
var ReactPropTransferer = require('ReactPropTransferer');
@@ -877,7 +878,10 @@ var ReactCompositeComponentMixin = {
continue;
}
var method = this.__reactAutoBindMap[autoBindKey];
this[autoBindKey] = this._bindAutoBindMethod(method);
this[autoBindKey] = ReactErrorUtils.guard(
this._bindAutoBindMethod(method),
this.constructor.displayName + '.' + autoBindKey
);
}
},
@@ -0,0 +1,46 @@
/**
* Copyright 2013 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @jsx React.DOM
* @emails react-core
*/
"use strict";
var React = require('React');
var ReactTestUtils = require('ReactTestUtils');
var ReactErrorUtils;
describe('ReactCompositeComponent-error', function() {
beforeEach(function() {
ReactErrorUtils = require('ReactErrorUtils');
});
it('should be passed the component and method name', function() {
var Component = React.createClass({
someHandler: function() {},
render: function() {
return <div />;
}
});
var instance = <Component />;
ReactTestUtils.renderIntoDocument(instance);
expect(ReactErrorUtils.guard.mock.calls[0][1])
.toEqual('Component.someHandler');
});
});
+44
View File
@@ -0,0 +1,44 @@
/**
* Copyright 2013 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @providesModule ReactErrorUtils
* @typechecks
*/
var ReactErrorUtils = {
/**
* Creates a guarded version of a function. This is supposed to make debugging
* of event handlers easier. This implementation provides only basic error
* logging and re-throws the error.
*
* @param {function} func Function to be executed
* @param {string} name The name of the guard
* @return {function}
*/
guard: function(func, name) {
return function guarded() {
try {
return func.apply(this, arguments);
} catch(ex) {
if (__DEV__) {
console.error(name + ': ' + ex.message);
}
throw ex;
}
};
}
};
module.exports = ReactErrorUtils;