Repository URL to install this package:
|
Version:
1.3.2 ▾
|
/**
* @file this is for react error handling to help encapsulate errors
*
* @spec
* https://github.com/v8/v8/wiki/Stack-Trace-API
*
* @discussions
* https://github.com/facebook/react/issues/2461#issuecomment-158787924
* https://github.com/facebook/react/pull/5615
* https://github.com/skiano/react-safe-render/blob/feature/safe-methods/index.js
* https://docs.google.com/document/d/1rda3yKGHimKIhg5YeoAmCOtyURgsbTH_qaYR79FELlk/edit#heading=h.sdpzjcyw06a5
*
* @libs
* https://www.stacktracejs.com/
* https://github.com/felixge/node-stack-trace
*/
import React from 'react'
import { stringify } from 'chain-able-boost'
import { isString, isEmpty, isFunction, EMPTY_OBJ } from 'exotic'
import { fromStringToStyle } from 'view-container'
// override of exotic
const isNotEmpty = x => isString(x) && !isEmpty(x) && x.trim() !== '.'
// @todo clean this out
let errorLines = 0
const toFormattedErrorLines = error => {
const listItems = error
.split(/((\n+)|(\.\s+))/)
.filter(isNotEmpty)
.map(line => {
return (
<li key={(errorLines += 1 + '@error')}>
<small>{line}</small>
</li>
)
})
// is ordered but numbers don't work well
return <ul>{listItems}</ul>
}
const styles = fromStringToStyle(`
section {
padding: 1rem;
}
ul {
color: rgba(0, 0, 0, .3);
}
h2 {
padding: 1rem;
color: black;
background-color: red;
}
pre {
background-color: #fefefe;
border: 2px solid #aeaeae;
font: monospace;
}
`)
/**
* @tutorial https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html
* @see https://github.com/commissure/redbox-react
* @see https://github.com/bvaughn/react-error-boundary
*/
class ErrorBoundary extends React.Component {
state = {
hasError: false,
error: undefined,
stack: undefined,
}
componentDidCatch(error, info = EMPTY_OBJ) {
const debugStack = isFunction(window.debuggable)
? window.debuggable(error)
: error
// const debugStack = window.debuggable.stackAt(7)
const stack = stringify(debugStack, null, 2)
console.warn(debugStack)
console.log(error, info)
this.setState({ hasError: true, error, stack, info })
}
render() {
const { name } = this.props
const { error, hasError, stack, info } = this.state
if (hasError === true) {
// JSON.stringify(error, null, 2)
const errorView = error.message ? error.message : error.stack
return (
<div>
{styles}
<section>
<h1>{name} Component Error</h1>
<h2>PLEASE CHECK YOUR DEV CONSOLE</h2>
<div>{toFormattedErrorLines(errorView)}</div>
<pre>
<code>{info.componentStack}</code>
</pre>
<pre>{stack}</pre>
</section>
</div>
)
}
return this.props.children
}
}
function withErrorBoundary() {
return function withComponent(Component) {
return function renderWithErrorBoundaryWithComponent(props) {
return (
<ErrorBoundary>
<Component {...props} />
</ErrorBoundary>
)
}
}
}
export { withErrorBoundary }
export { ErrorBoundary }
export default ErrorBoundary