@ -1,6 +1,7 @@
import React from 'react' ;
import React from 'react' ;
import PropTypes from 'prop-types' ;
import PropTypes from 'prop-types' ;
import illustration from '../../images/elephant_ui_disappointed.svg' ;
import { FormattedMessage } from 'react-intl' ;
import { version , source _url } from 'mastodon/initial_state' ;
export default class ErrorBoundary extends React . PureComponent {
export default class ErrorBoundary extends React . PureComponent {
@ -12,26 +13,53 @@ export default class ErrorBoundary extends React.PureComponent {
hasError : false ,
hasError : false ,
stackTrace : undefined ,
stackTrace : undefined ,
componentStack : undefined ,
componentStack : undefined ,
}
} ;
componentDidCatch ( error , info ) {
componentDidCatch ( error , info ) {
this . setState ( {
this . setState ( {
hasError : true ,
hasError : true ,
stackTrace : error . stack ,
stackTrace : error . stack ,
componentStack : info && info . componentStack ,
componentStack : info && info . componentStack ,
copied : false ,
} ) ;
} ) ;
}
}
handleCopyStackTrace = ( ) => {
const { stackTrace } = this . state ;
const textarea = document . createElement ( 'textarea' ) ;
textarea . textContent = stackTrace ;
textarea . style . position = 'fixed' ;
document . body . appendChild ( textarea ) ;
try {
textarea . select ( ) ;
document . execCommand ( 'copy' ) ;
} catch ( e ) {
} finally {
document . body . removeChild ( textarea ) ;
}
this . setState ( { copied : true } ) ;
setTimeout ( ( ) => this . setState ( { copied : false } ) , 700 ) ;
}
render ( ) {
render ( ) {
const { hasError } = this . state ;
const { hasError , copied } = this . state ;
if ( ! hasError ) {
if ( ! hasError ) {
return this . props . children ;
return this . props . children ;
}
}
return (
return (
< div >
< div className = 'error-boundary' >
< img src = { illustration } alt = '' / >
< div >
< p className = 'error-boundary__error' > < FormattedMessage id = 'error.unexpected_crash.explanation' defaultMessage = 'Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.' / > < / p >
< p > < FormattedMessage id = 'error.unexpected_crash.next_steps' defaultMessage = 'Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.' / > < / p >
< p className = 'error-boundary__footer' > Mastodon v { version } · < a href = { source _url } rel = 'noopener' target = '_blank' > < FormattedMessage id = 'errors.unexpected_crash.report_issue' defaultMessage = 'Report issue' / > < /a> · <button onClick={this.handleCopyStackTrace} className={copied && 'copied'}><FormattedMessage id='errors.unexpected_crash.copy_stacktrace' defaultMessage='Copy stacktrace to clipboard' / > < / b u t t o n > < / p >
< / d i v >
< / d i v >
< / d i v >
) ;
) ;
}
}