Created
September 16, 2019 15:46
-
-
Save jaredreich/81703695011d1ca1b86b853c1739fbf7 to your computer and use it in GitHub Desktop.
Scoped component async event error handling in React
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const reservedClassMethodNames = { | |
componentDidCatch: 1, | |
componentDidMount: 1, | |
componentDidUpdate: 1, | |
componentWillMount: 1, | |
componentWillReceiveProps: 1, | |
componentWillUnmount: 1, | |
componentWillUpdate: 1, | |
constructor: 1, | |
getDerivedStateFromError: 1, | |
getDerivedStateFromProps: 1, | |
getSnapshotBeforeUpdate: 1, | |
render: 1, | |
shouldComponentUpdate: 1, | |
}; | |
function wrapErrors(fn, handleError) { | |
// don't wrap function more than once | |
if (!fn.__wrapped__) { | |
fn.__wrapped__ = function () { | |
try { | |
return fn.apply(this, arguments); | |
} catch (error) { | |
handleError && handleError(error); // report the error | |
throw error; // re-throw the error | |
} | |
}; | |
} | |
return fn.__wrapped__; | |
} | |
const composeWithAsyncErrorHandling = (handleError) => (Component) => { | |
const classMethodNames = Object.getOwnPropertyNames(Component.prototype); | |
classMethodNames.forEach(methodName => { | |
if (!reservedClassMethodNames[methodName]) { | |
Component.prototype[methodName] = wrapErrors(Component.prototype[methodName], handleError); | |
} | |
}); | |
return Component; | |
}; | |
export default composeWithAsyncErrorHandling((error) => { | |
console.log('=== CAPTURED ASYNC ERROR, SEND IT TO LOGGER!'); | |
console.log(error); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment