import * as React from 'react'; import versionInfo from '@joplin/lib/versionInfo'; import PluginService from '@joplin/lib/services/plugins/PluginService'; import Setting from '@joplin/lib/models/Setting'; import bridge from '../services/bridge'; const packageInfo = require('../packageInfo.js'); const ipcRenderer = require('electron').ipcRenderer; interface ErrorInfo { componentStack: string; } interface PluginInfo { id: string; name: string; enabled: boolean; version: string; } interface State { error: Error; errorInfo: ErrorInfo; pluginInfos: PluginInfo[]; } interface Props { message?: string; } export default class ErrorBoundary extends React.Component { public state: State = { error: null, errorInfo: null, pluginInfos: [] }; componentDidCatch(error: any, errorInfo: ErrorInfo) { if (typeof error === 'string') error = { message: error }; const pluginInfos: PluginInfo[] = []; try { const service = PluginService.instance(); const pluginSettings = service.unserializePluginSettings(Setting.value('plugins.states')); for (const pluginId in pluginSettings) { const plugin = PluginService.instance().pluginById(pluginId); pluginInfos.push({ id: pluginId, name: plugin.manifest.name, enabled: pluginSettings[pluginId].enabled, version: plugin.manifest.version, }); } } catch (error) { console.error('Could not get plugin info:', error); } this.setState({ error, errorInfo, pluginInfos }); } componentDidMount() { const onAppClose = () => { ipcRenderer.send('asynchronous-message', 'appCloseReply', { canClose: true, }); }; ipcRenderer.on('appClose', onAppClose); } renderMessage() { const message = this.props.message || 'Joplin encountered a fatal error and could not continue.'; return

{message}

; } render() { if (this.state.error) { const safeMode_click = async () => { Setting.setValue('isSafeMode', true); await Setting.saveAll(); bridge().restart(); }; try { const output = []; output.push(

Message

{this.state.error.message}

); output.push(

Version info

{versionInfo(packageInfo).message}
); if (this.state.pluginInfos.length) { output.push(

Plugins

{JSON.stringify(this.state.pluginInfos, null, 4)}
); } if (this.state.error.stack) { output.push(

Stack trace

{this.state.error.stack}
); } if (this.state.errorInfo) { if (this.state.errorInfo.componentStack) { output.push(

Component stack

{this.state.errorInfo.componentStack}
); } } return (

Error

{this.renderMessage()}

To report the error, please copy the *entire content* of this page and post it on Joplin forum or GitHub.

If the error persists you may try to restart in safe mode, which will temporarily disable all plugins.

{output}
); } catch (error) { return (
{JSON.stringify(this.state)}
); } } return this.props.children; } }