You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
3.2 KiB

  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { FormattedMessage } from 'react-intl';
  4. import { preferencesLink } from 'flavours/glitch/util/backend_links';
  5. export default class ErrorBoundary extends React.PureComponent {
  6. static propTypes = {
  7. children: PropTypes.node,
  8. };
  9. state = {
  10. hasError: false,
  11. stackTrace: undefined,
  12. componentStack: undefined,
  13. }
  14. componentDidCatch(error, info) {
  15. this.setState({
  16. hasError: true,
  17. stackTrace: error.stack,
  18. componentStack: info && info.componentStack,
  19. });
  20. }
  21. handleReload(e) {
  22. e.preventDefault();
  23. window.location.reload();
  24. }
  25. render() {
  26. const { hasError, stackTrace, componentStack } = this.state;
  27. if (!hasError) return this.props.children;
  28. let debugInfo = '';
  29. if (stackTrace) {
  30. debugInfo += 'Stack trace\n-----------\n\n```\n' + stackTrace.toString() + '\n```';
  31. }
  32. if (componentStack) {
  33. if (debugInfo) {
  34. debugInfo += '\n\n\n';
  35. }
  36. debugInfo += 'React component stack\n---------------------\n\n```\n' + componentStack.toString() + '\n```';
  37. }
  38. return (
  39. <div tabIndex='-1'>
  40. <div className='error-boundary'>
  41. <h1><FormattedMessage id='web_app_crash.title' defaultMessage="We're sorry, but something went wrong with the Mastodon app." /></h1>
  42. <p>
  43. <FormattedMessage id='web_app_crash.content' defaultMessage='You could try any of the following:' />
  44. <ul>
  45. <li>
  46. <FormattedMessage
  47. id='web_app_crash.report_issue'
  48. defaultMessage='Report a bug in the {issuetracker}'
  49. values={{ issuetracker: <a href='https://github.com/glitch-soc/mastodon/issues' rel='noopener' target='_blank'><FormattedMessage id='web_app_crash.issue_tracker' defaultMessage='issue tracker' /></a> }}
  50. />
  51. { debugInfo !== '' && (
  52. <details>
  53. <summary><FormattedMessage id='web_app_crash.debug_info' defaultMessage='Debug information' /></summary>
  54. <textarea
  55. className='web_app_crash-stacktrace'
  56. value={debugInfo}
  57. rows='10'
  58. readOnly
  59. />
  60. </details>
  61. )}
  62. </li>
  63. <li>
  64. <FormattedMessage
  65. id='web_app_crash.reload_page'
  66. defaultMessage='{reload} the current page'
  67. values={{ reload: <a href='#' onClick={this.handleReload}><FormattedMessage id='web_app_crash.reload' defaultMessage='Reload' /></a> }}
  68. />
  69. </li>
  70. { preferencesLink !== undefined && (
  71. <li>
  72. <FormattedMessage
  73. id='web_app_crash.change_your_settings'
  74. defaultMessage='Change your {settings}'
  75. values={{ settings: <a href={preferencesLink}><FormattedMessage id='web_app_crash.settings' defaultMessage='settings' /></a> }}
  76. />
  77. </li>
  78. )}
  79. </ul>
  80. </p>
  81. </div>
  82. </div>
  83. );
  84. }
  85. }