Change error boundary to upstream's (#2323)
This commit is contained in:
		
							parent
							
								
									6fb2982ec0
								
							
						
					
					
						commit
						eed89bc69f
					
				
					 4 changed files with 51 additions and 108 deletions
				
			
		| 
						 | 
					@ -7,8 +7,7 @@ import { Helmet } from 'react-helmet';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import StackTrace from 'stacktrace-js';
 | 
					import StackTrace from 'stacktrace-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { source_url } from 'flavours/glitch/initial_state';
 | 
					import { version, source_url } from 'flavours/glitch/initial_state';
 | 
				
			||||||
import { preferencesLink } from 'flavours/glitch/utils/backend_links';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class ErrorBoundary extends PureComponent {
 | 
					export default class ErrorBoundary extends PureComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +23,7 @@ export default class ErrorBoundary extends PureComponent {
 | 
				
			||||||
    componentStack: undefined,
 | 
					    componentStack: undefined,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentDidCatch(error, info) {
 | 
					  componentDidCatch (error, info) {
 | 
				
			||||||
    this.setState({
 | 
					    this.setState({
 | 
				
			||||||
      hasError: true,
 | 
					      hasError: true,
 | 
				
			||||||
      errorMessage: error.toString(),
 | 
					      errorMessage: error.toString(),
 | 
				
			||||||
| 
						 | 
					@ -44,88 +43,62 @@ export default class ErrorBoundary extends PureComponent {
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleReload(e) {
 | 
					  handleCopyStackTrace = () => {
 | 
				
			||||||
    e.preventDefault();
 | 
					    const { errorMessage, stackTrace, mappedStackTrace } = this.state;
 | 
				
			||||||
    window.location.reload();
 | 
					    const textarea = document.createElement('textarea');
 | 
				
			||||||
  }
 | 
					
 | 
				
			||||||
 | 
					    let contents = [errorMessage, stackTrace];
 | 
				
			||||||
 | 
					    if (mappedStackTrace) {
 | 
				
			||||||
 | 
					      contents.push(mappedStackTrace);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    textarea.textContent    = contents.join('\n\n\n');
 | 
				
			||||||
 | 
					    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, errorMessage, stackTrace, mappedStackTrace, componentStack } = this.state;
 | 
					    const { hasError, copied, errorMessage } = this.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!hasError) return this.props.children;
 | 
					    if (!hasError) {
 | 
				
			||||||
 | 
					      return this.props.children;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const likelyBrowserAddonIssue = errorMessage && errorMessage.includes('NotFoundError');
 | 
					    const likelyBrowserAddonIssue = errorMessage && errorMessage.includes('NotFoundError');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let debugInfo = '';
 | 
					 | 
				
			||||||
    if (stackTrace) {
 | 
					 | 
				
			||||||
      debugInfo += 'Stack trace\n-----------\n\n```\n' + errorMessage + '\n' + stackTrace.toString() + '\n```';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (mappedStackTrace) {
 | 
					 | 
				
			||||||
      debugInfo += 'Mapped stack trace\n-----------\n\n```\n' + errorMessage + '\n' + mappedStackTrace.toString() + '\n```';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (componentStack) {
 | 
					 | 
				
			||||||
      if (debugInfo) {
 | 
					 | 
				
			||||||
        debugInfo += '\n\n\n';
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      debugInfo += 'React component stack\n---------------------\n\n```\n' + componentStack.toString() + '\n```';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let issueTracker = source_url;
 | 
					 | 
				
			||||||
    if (source_url.match(/^https:\/\/github\.com\/[^/]+\/[^/]+\/?$/)) {
 | 
					 | 
				
			||||||
      issueTracker = source_url + '/issues';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <div tabIndex={-1}>
 | 
					      <div className='error-boundary'>
 | 
				
			||||||
        <div className='error-boundary'>
 | 
					        <div>
 | 
				
			||||||
          <h1><FormattedMessage id='web_app_crash.title' defaultMessage="We're sorry, but something went wrong with the Mastodon app." /></h1>
 | 
					          <p className='error-boundary__error'>
 | 
				
			||||||
          <p>
 | 
					            { likelyBrowserAddonIssue ? (
 | 
				
			||||||
            <FormattedMessage id='web_app_crash.content' defaultMessage='You could try any of the following:' />
 | 
					              <FormattedMessage id='error.unexpected_crash.explanation_addons' defaultMessage='This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.' />
 | 
				
			||||||
          </p>
 | 
					            ) : (
 | 
				
			||||||
          <ul>
 | 
					              <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.' />
 | 
				
			||||||
            { likelyBrowserAddonIssue && (
 | 
					 | 
				
			||||||
              <li>
 | 
					 | 
				
			||||||
                <FormattedMessage
 | 
					 | 
				
			||||||
                  id='web_app_crash.disable_addons'
 | 
					 | 
				
			||||||
                  defaultMessage='Disable browser add-ons or built-in translation tools'
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
              </li>
 | 
					 | 
				
			||||||
            ) }
 | 
					 | 
				
			||||||
            <li>
 | 
					 | 
				
			||||||
              <FormattedMessage
 | 
					 | 
				
			||||||
                id='web_app_crash.report_issue'
 | 
					 | 
				
			||||||
                defaultMessage='Report a bug in the {issuetracker}'
 | 
					 | 
				
			||||||
                values={{ issuetracker: <a href={issueTracker} rel='noopener noreferrer' target='_blank'><FormattedMessage id='web_app_crash.issue_tracker' defaultMessage='issue tracker' /></a> }}
 | 
					 | 
				
			||||||
              />
 | 
					 | 
				
			||||||
              { debugInfo !== '' && (
 | 
					 | 
				
			||||||
                <details>
 | 
					 | 
				
			||||||
                  <summary><FormattedMessage id='web_app_crash.debug_info' defaultMessage='Debug information' /></summary>
 | 
					 | 
				
			||||||
                  <textarea
 | 
					 | 
				
			||||||
                    className='web_app_crash-stacktrace'
 | 
					 | 
				
			||||||
                    value={debugInfo}
 | 
					 | 
				
			||||||
                    rows='10'
 | 
					 | 
				
			||||||
                    readOnly
 | 
					 | 
				
			||||||
                  />
 | 
					 | 
				
			||||||
                </details>
 | 
					 | 
				
			||||||
              )}
 | 
					 | 
				
			||||||
            </li>
 | 
					 | 
				
			||||||
            <li>
 | 
					 | 
				
			||||||
              <FormattedMessage
 | 
					 | 
				
			||||||
                id='web_app_crash.reload_page'
 | 
					 | 
				
			||||||
                defaultMessage='{reload} the current page'
 | 
					 | 
				
			||||||
                values={{ reload: <a href='#' onClick={this.handleReload}><FormattedMessage id='web_app_crash.reload' defaultMessage='Reload' /></a> }}
 | 
					 | 
				
			||||||
              />
 | 
					 | 
				
			||||||
            </li>
 | 
					 | 
				
			||||||
            { preferencesLink !== undefined && (
 | 
					 | 
				
			||||||
              <li>
 | 
					 | 
				
			||||||
                <FormattedMessage
 | 
					 | 
				
			||||||
                  id='web_app_crash.change_your_settings'
 | 
					 | 
				
			||||||
                  defaultMessage='Change your {settings}'
 | 
					 | 
				
			||||||
                  values={{ settings: <a href={preferencesLink}><FormattedMessage id='web_app_crash.settings' defaultMessage='settings' /></a> }}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
              </li>
 | 
					 | 
				
			||||||
            )}
 | 
					            )}
 | 
				
			||||||
          </ul>
 | 
					          </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <p>
 | 
				
			||||||
 | 
					            { likelyBrowserAddonIssue ? (
 | 
				
			||||||
 | 
					              <FormattedMessage id='error.unexpected_crash.next_steps_addons' defaultMessage='Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.' />
 | 
				
			||||||
 | 
					            ) : (
 | 
				
			||||||
 | 
					              <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 noreferrer' 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' /></button></p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <Helmet>
 | 
					        <Helmet>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -200,6 +200,7 @@ button {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.error-boundary,
 | 
				
			||||||
.app-holder noscript {
 | 
					.app-holder noscript {
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
  font-size: 16px;
 | 
					  font-size: 16px;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,30 +0,0 @@
 | 
				
			||||||
.error-boundary {
 | 
					 | 
				
			||||||
  color: $primary-text-color;
 | 
					 | 
				
			||||||
  font-size: 15px;
 | 
					 | 
				
			||||||
  line-height: 20px;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  h1 {
 | 
					 | 
				
			||||||
    font-size: 26px;
 | 
					 | 
				
			||||||
    line-height: 36px;
 | 
					 | 
				
			||||||
    font-weight: 400;
 | 
					 | 
				
			||||||
    margin-bottom: 8px;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  a {
 | 
					 | 
				
			||||||
    color: $primary-text-color;
 | 
					 | 
				
			||||||
    text-decoration: underline;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ul {
 | 
					 | 
				
			||||||
    list-style: disc;
 | 
					 | 
				
			||||||
    margin-inline-start: 0;
 | 
					 | 
				
			||||||
    padding-inline-start: 1em;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  textarea.web_app_crash-stacktrace {
 | 
					 | 
				
			||||||
    width: 100%;
 | 
					 | 
				
			||||||
    resize: none;
 | 
					 | 
				
			||||||
    white-space: pre;
 | 
					 | 
				
			||||||
    font-family: $font-monospace, monospace;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,6 @@
 | 
				
			||||||
@import 'lists';
 | 
					@import 'lists';
 | 
				
			||||||
@import 'emoji_picker';
 | 
					@import 'emoji_picker';
 | 
				
			||||||
@import 'local_settings';
 | 
					@import 'local_settings';
 | 
				
			||||||
@import 'error_boundary';
 | 
					 | 
				
			||||||
@import 'single_column';
 | 
					@import 'single_column';
 | 
				
			||||||
@import 'announcements';
 | 
					@import 'announcements';
 | 
				
			||||||
@import 'explore';
 | 
					@import 'explore';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue