Skip to content

Commit 71559c8

Browse files
committed
feat: add ErrorBoundary
1 parent 6a6e1f6 commit 71559c8

File tree

6 files changed

+142
-34
lines changed

6 files changed

+142
-34
lines changed

Cargo.lock

Lines changed: 34 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/desktop/src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ anyhow = "1.0.75"
1818
dark-light = "1.0.0"
1919
log = "0.4.19"
2020
serde = { version = "1.0", features = ["derive"] }
21-
tauri = { version = "1.4.1", features = [ "window-set-title", "window-start-dragging", "clipboard-write-text", "dialog-open", "dialog-save", "fs-exists", "fs-read-file", "fs-write-file", "global-shortcut-all", "os-all", "path-all", "window-close", "window-create", "devtools"] }
21+
tauri = { version = "1.4.1", features = [ "shell-open", "window-set-title", "window-start-dragging", "clipboard-write-text", "dialog-open", "dialog-save", "fs-exists", "fs-read-file", "fs-write-file", "global-shortcut-all", "os-all", "path-all", "window-close", "window-create", "devtools"] }
2222
tauri-plugin-store = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
2323
regex = "1.9.3"
2424
mf-utils = { path = "../../../crates/utils" }

apps/desktop/src-tauri/tauri.conf.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
"create": true,
4747
"setTitle": true,
4848
"startDragging": true
49+
},
50+
"shell": {
51+
"open": true
4952
}
5053
},
5154
"bundle": {
@@ -80,4 +83,4 @@
8083
}
8184
}
8285
}
83-
}
86+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import type { ErrorInfo, PropsWithChildren } from 'react'
2+
import React from 'react'
3+
import styled from 'styled-components'
4+
5+
const Title = styled.h1`
6+
color: ${({ theme }) => theme.warnColor};
7+
`
8+
9+
interface ErrorBoundaryProps {
10+
hasError?: boolean
11+
error?: unknown
12+
}
13+
14+
class ErrorBoundary extends React.Component<
15+
PropsWithChildren<ErrorBoundaryProps>,
16+
{ hasError: boolean }
17+
> {
18+
constructor(props: PropsWithChildren<ErrorBoundaryProps>) {
19+
super(props)
20+
this.state = { hasError: this.props.hasError ?? false }
21+
}
22+
23+
static getDerivedStateFromError() {
24+
return { hasError: true }
25+
}
26+
27+
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
28+
console.error('[ErrorBoundary]', error, errorInfo)
29+
}
30+
31+
render() {
32+
if (this.state.hasError) {
33+
return (
34+
<>
35+
<Title data-testid='editor_error'>Sorry, something went wrong!</Title>
36+
<p>{String(this.props.error)}</p>
37+
<a
38+
href='https://github.com/linebyline-group/linebyline/issues/new/choose'
39+
target='_blank'
40+
rel='noreferrer'
41+
>
42+
Please tell us about it and we will fix it in less time
43+
</a>
44+
</>
45+
)
46+
}
47+
48+
return this.props.children
49+
}
50+
}
51+
52+
export default ErrorBoundary

packages/editor/src/components/SourceEditor/index.tsx

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,46 @@
1-
import { Remirror} from '@remirror/react'
1+
import { Remirror } from '@remirror/react'
22
import { createContextState } from 'create-context-state'
33
import React, { memo } from 'react'
44
import Text from '../Text'
55
import type { EditorDelegate } from '../../types'
6-
import { ProsemirrorDevTools } from "@remirror/dev"
6+
import { ProsemirrorDevTools } from '@remirror/dev'
77
import { createSourceCodeDelegate } from './delegate'
8+
import ErrorBoundary from '../ErrorBoundary'
89

910
type Context = Props
1011

1112
type Props = {
1213
markText: EditorDelegate
1314
} & Partial<SourceCodeEditorProps>
1415

15-
const [SourceEditorProvider, useSourceCodeEditor] = createContextState<Context, Props>(({ props }) => {
16-
return {
17-
...props,
18-
}
19-
})
16+
const [SourceEditorProvider, useSourceCodeEditor] = createContextState<Context, Props>(
17+
({ props }) => {
18+
return {
19+
...props,
20+
}
21+
},
22+
)
2023

2124
const SourceCodeEditorCore = memo((props: { markdownToolBar?: React.ReactNode[] }) => {
2225
const { markdownToolBar } = props
2326
const { content, markText, hooks, isTesting } = useSourceCodeEditor()
2427

28+
let initialCntent
29+
30+
try {
31+
initialCntent = markText.stringToDoc(content!)
32+
} catch (error) {
33+
return <ErrorBoundary hasError error={error} />
34+
}
35+
2536
return (
26-
<Remirror
27-
manager={markText.manager}
28-
initialContent={markText.stringToDoc(content!)}
29-
hooks={hooks}
30-
>
31-
<Text className='h-full w-full overflow-auto px-0' style={{ padding: 0 }} />
32-
{markdownToolBar || null}
33-
{isTesting ? <ProsemirrorDevTools /> : null}
34-
</Remirror>
37+
<ErrorBoundary>
38+
<Remirror manager={markText.manager} initialContent={initialCntent} hooks={hooks}>
39+
<Text className='h-full w-full overflow-auto px-0' style={{ padding: 0 }} />
40+
{markdownToolBar || null}
41+
{isTesting ? <ProsemirrorDevTools /> : null}
42+
</Remirror>
43+
</ErrorBoundary>
3544
)
3645
})
3746

packages/editor/src/components/WysiwygEditor/index.tsx

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import Wrapper from '../Wrapper'
55
import { createWysiwygDelegate } from './delegate'
66
import type { EditorDelegate } from '../../types'
77
import TableToolbar from '../../toolbar/TableToolbar'
8-
import { ProsemirrorDevTools } from "@remirror/dev"
9-
import React from "react"
8+
import { ProsemirrorDevTools } from '@remirror/dev'
9+
import React from 'react'
10+
import ErrorBoundary from '../ErrorBoundary'
1011

1112
export const OffsetContext = createContext({ top: 0, left: 0 })
1213

@@ -15,21 +16,30 @@ const WysiwygEditor: FC<WysiwygEditorProps> = (props) => {
1516

1617
const editorDelegate = delegate ?? createWysiwygDelegate()
1718

19+
let initialContent
20+
try {
21+
initialContent = editorDelegate.stringToDoc(content)
22+
} catch (error) {
23+
return <ErrorBoundary hasError error={error}/>
24+
}
25+
1826
return (
19-
<Wrapper>
20-
<OffsetContext.Provider value={offset || { top: 0, left: 0 }}>
21-
<Remirror
22-
manager={editorDelegate.manager}
23-
initialContent={editorDelegate.stringToDoc(content)}
24-
hooks={hooks}
25-
>
26-
<TableToolbar />
27-
{wysiwygToolBar || null}
28-
<Text className="w-full markdown-body" />
29-
{isTesting ? <ProsemirrorDevTools /> : null}
30-
</Remirror>
31-
</OffsetContext.Provider>
32-
</Wrapper>
27+
<ErrorBoundary>
28+
<Wrapper>
29+
<OffsetContext.Provider value={offset || { top: 0, left: 0 }}>
30+
<Remirror
31+
manager={editorDelegate.manager}
32+
initialContent={initialContent}
33+
hooks={hooks}
34+
>
35+
<TableToolbar />
36+
{wysiwygToolBar || null}
37+
<Text className='w-full markdown-body' />
38+
{isTesting ? <ProsemirrorDevTools /> : null}
39+
</Remirror>
40+
</OffsetContext.Provider>
41+
</Wrapper>
42+
</ErrorBoundary>
3343
)
3444
}
3545

0 commit comments

Comments
 (0)