Add error boundary
This commit is contained in:
		
							parent
							
								
									840cb5b182
								
							
						
					
					
						commit
						ccb9da9333
					
				
					 17 changed files with 13649 additions and 18020 deletions
				
			
		|  | @ -21,7 +21,7 @@ import NotificationsOffIcon from '@mui/icons-material/NotificationsOff'; | |||
| import api from "../app/Api"; | ||||
| import routes from "./routes"; | ||||
| import subscriptionManager from "../app/SubscriptionManager"; | ||||
| import logo from "../img/ntfy.svg" | ||||
| import logo from "../img/ntfy.svg"; | ||||
| 
 | ||||
| const ActionBar = (props) => { | ||||
|     const location = useLocation(); | ||||
|  |  | |||
|  | @ -31,21 +31,21 @@ import {useAutoSubscribe, useConnectionListeners} from "./hooks"; | |||
| 
 | ||||
| const App = () => { | ||||
|     return ( | ||||
|         <ErrorBoundary> | ||||
|             <BrowserRouter> | ||||
|                 <ThemeProvider theme={theme}> | ||||
|                     <CssBaseline/> | ||||
|         <BrowserRouter> | ||||
|             <ThemeProvider theme={theme}> | ||||
|                 <CssBaseline/> | ||||
|                 <ErrorBoundary> | ||||
|                     <Routes> | ||||
|                         <Route element={<Layout/>}> | ||||
|                             <Route path={routes.root} element={<AllSubscriptions/>} /> | ||||
|                             <Route path={routes.settings} element={<Preferences/>} /> | ||||
|                             <Route path={routes.subscription} element={<SingleSubscription/>} /> | ||||
|                             <Route path={routes.subscriptionExternal} element={<SingleSubscription/>} /> | ||||
|                             <Route path={routes.root} element={<AllSubscriptions/>}/> | ||||
|                             <Route path={routes.settings} element={<Preferences/>}/> | ||||
|                             <Route path={routes.subscription} element={<SingleSubscription/>}/> | ||||
|                             <Route path={routes.subscriptionExternal} element={<SingleSubscription/>}/> | ||||
|                         </Route> | ||||
|                     </Routes> | ||||
|                 </ThemeProvider> | ||||
|             </BrowserRouter> | ||||
|         </ErrorBoundary> | ||||
|                 </ErrorBoundary> | ||||
|             </ThemeProvider> | ||||
|         </BrowserRouter> | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,27 +1,64 @@ | |||
| import * as React from "react"; | ||||
| import StackTrace from "stacktrace-js"; | ||||
| import {CircularProgress} from "@mui/material"; | ||||
| import Button from "@mui/material/Button"; | ||||
| 
 | ||||
| class ErrorBoundary extends React.Component { | ||||
|     constructor(props) { | ||||
|         super(props); | ||||
|         this.state = { error: null, info: null }; | ||||
|         this.state = { error: null, info: null, stack: null }; | ||||
|     } | ||||
| 
 | ||||
|     componentDidCatch(error, info) { | ||||
|         this.setState({ error, info }); | ||||
|         console.error("[ErrorBoundary] A horrible error occurred", info); | ||||
|         console.error("[ErrorBoundary] Error caught", error, info); | ||||
|         StackTrace.fromError(error).then(stack => { | ||||
|             console.error("[ErrorBoundary] Stacktrace fetched", stack); | ||||
|             const stackStr = stack.map( el => { | ||||
|                 return `  at ${el.functionName} (${el.fileName}:${el.columnNumber}:${el.lineNumber})\n`; | ||||
|             }) | ||||
|             this.setState({ stack: stackStr }) | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     static getDerivedStateFromError(error) { | ||||
|         return { error: true, errorMessage: error.toString() } | ||||
|     copyStack() { | ||||
|         let stack = ""; | ||||
|         if (this.state.stack) { | ||||
|             stack += `Stack trace:\n${this.state.error}\n${this.state.stack}\n\n`; | ||||
|         } | ||||
|         stack += `Original stack trace:\n${this.state.error}\n${this.state.info.componentStack}\n\n`; | ||||
|         navigator.clipboard.writeText(stack); | ||||
|     } | ||||
| 
 | ||||
|     render() { | ||||
|         if (this.state.info) { | ||||
|             return ( | ||||
|                 <div> | ||||
|                     <h2>Something went wrong.</h2> | ||||
|                     <pre>{this.state.error && this.state.error.toString()}</pre> | ||||
|                     <pre>{this.state.info.componentStack}</pre> | ||||
|                 <div style={{margin: '20px'}}> | ||||
|                     <h2>Oh no, ntfy crashed 😮</h2> | ||||
|                     <p> | ||||
|                         This should obviously not happen. Very sorry about this.<br/> | ||||
|                         If you have a minute, please <a href="https://github.com/binwiederhier/ntfy/issues">report this on GitHub</a>, or let us | ||||
|                         know via <a href="https://discord.gg/cT7ECsZj9w">Discord</a> or <a href="https://matrix.to/#/#ntfy:matrix.org">Matrix</a>. | ||||
|                     </p> | ||||
|                     <p> | ||||
|                         <Button variant="outlined" onClick={() => this.copyStack()}>Copy stack trace</Button> | ||||
|                     </p> | ||||
|                     <h3>Stack trace</h3> | ||||
|                     {this.state.stack | ||||
|                         ? | ||||
|                             <pre> | ||||
|                                 {this.state.error && this.state.error.toString()}{"\n"} | ||||
|                                 {this.state.stack} | ||||
|                             </pre> | ||||
|                         : | ||||
|                             <> | ||||
|                                 <CircularProgress size="20px" sx={{verticalAlign: "text-bottom"}}/> Gather more info ... | ||||
|                             </> | ||||
|                     } | ||||
|                     <pre> | ||||
|                         {this.state.error && this.state.error.toString()} | ||||
|                         {this.state.info.componentStack} | ||||
|                     </pre> | ||||
|                 </div> | ||||
|             ); | ||||
|         } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue