Merge pull request #471 from outline/jori/document-error-boundary
More detailed error boundary for Document
This commit is contained in:
@ -8,7 +8,7 @@ type Props = {
|
||||
|
||||
const Container = styled.div`
|
||||
width: 100%;
|
||||
margin: 60px;
|
||||
padding: 60px;
|
||||
`;
|
||||
|
||||
const Content = styled.div`
|
||||
|
@ -5,8 +5,13 @@ import { observable } from 'mobx';
|
||||
import CenteredContent from 'components/CenteredContent';
|
||||
import PageTitle from 'components/PageTitle';
|
||||
|
||||
type Props = {
|
||||
children?: ?React.Element<any>,
|
||||
};
|
||||
|
||||
@observer
|
||||
class ErrorBoundary extends Component {
|
||||
props: Props;
|
||||
@observable error: boolean = false;
|
||||
|
||||
componentDidCatch(error: Error, info: Object) {
|
||||
@ -27,9 +32,10 @@ class ErrorBoundary extends Component {
|
||||
return (
|
||||
<CenteredContent>
|
||||
<PageTitle title="Something went wrong" />
|
||||
<h1>Something went wrong</h1>
|
||||
<h1>🛸 Something unexpected happened</h1>
|
||||
<p>
|
||||
An unrecoverable error occurred. Please try{' '}
|
||||
An unrecoverable error occurred{window.Bugsnag ||
|
||||
(true && ' and our engineers have been notified')}. Please try{' '}
|
||||
<a onClick={this.handleReload}>reloading</a>.
|
||||
</p>
|
||||
</CenteredContent>
|
||||
|
@ -33,6 +33,7 @@ import CenteredContent from 'components/CenteredContent';
|
||||
import PageTitle from 'components/PageTitle';
|
||||
import NewDocumentIcon from 'components/Icon/NewDocumentIcon';
|
||||
import Actions, { Action, Separator } from 'components/Actions';
|
||||
import ErrorBoundary from 'components/ErrorBoundary';
|
||||
import Search from 'scenes/Search';
|
||||
|
||||
const DISCARD_CHANGES = `
|
||||
@ -216,75 +217,77 @@ class DocumentScene extends Component {
|
||||
|
||||
return (
|
||||
<Container column auto>
|
||||
{isMoving && document && <DocumentMove document={document} />}
|
||||
{titleText && <PageTitle title={titleText} />}
|
||||
{(this.isLoading || this.isSaving) && <LoadingIndicator />}
|
||||
{isFetching && (
|
||||
<CenteredContent>
|
||||
<LoadingState />
|
||||
</CenteredContent>
|
||||
)}
|
||||
{!isFetching &&
|
||||
document && (
|
||||
<Flex justify="center" auto>
|
||||
<Prompt
|
||||
when={document.hasPendingChanges}
|
||||
message={DISCARD_CHANGES}
|
||||
/>
|
||||
<Editor
|
||||
key={`${document.id}-${document.revision}`}
|
||||
text={document.text}
|
||||
emoji={document.emoji}
|
||||
onImageUploadStart={this.onImageUploadStart}
|
||||
onImageUploadStop={this.onImageUploadStop}
|
||||
onChange={this.onChange}
|
||||
onSave={this.onSave}
|
||||
onCancel={this.onDiscard}
|
||||
readOnly={!this.isEditing}
|
||||
/>
|
||||
<Actions
|
||||
align="center"
|
||||
justify="flex-end"
|
||||
readOnly={!this.isEditing}
|
||||
>
|
||||
{!isNew &&
|
||||
!this.isEditing && <Collaborators document={document} />}
|
||||
<Action>
|
||||
{this.isEditing ? (
|
||||
<SaveAction
|
||||
isSaving={this.isSaving}
|
||||
onClick={this.onSave.bind(this, true)}
|
||||
disabled={
|
||||
!(this.document && this.document.allowSave) ||
|
||||
this.isSaving
|
||||
}
|
||||
isNew={!!isNew}
|
||||
/>
|
||||
) : (
|
||||
<a onClick={this.onClickEdit}>Edit</a>
|
||||
)}
|
||||
</Action>
|
||||
{this.isEditing && (
|
||||
<Action>
|
||||
<a onClick={this.onDiscard}>Discard</a>
|
||||
</Action>
|
||||
)}
|
||||
{!this.isEditing && (
|
||||
<Action>
|
||||
<DocumentMenu document={document} />
|
||||
</Action>
|
||||
)}
|
||||
{!this.isEditing && <Separator />}
|
||||
<Action>
|
||||
{!this.isEditing && (
|
||||
<a onClick={this.onClickNew}>
|
||||
<NewDocumentIcon />
|
||||
</a>
|
||||
)}
|
||||
</Action>
|
||||
</Actions>
|
||||
</Flex>
|
||||
<ErrorBoundary key={this.props.location.pathname}>
|
||||
{isMoving && document && <DocumentMove document={document} />}
|
||||
{titleText && <PageTitle title={titleText} />}
|
||||
{(this.isLoading || this.isSaving) && <LoadingIndicator />}
|
||||
{isFetching && (
|
||||
<CenteredContent>
|
||||
<LoadingState />
|
||||
</CenteredContent>
|
||||
)}
|
||||
{!isFetching &&
|
||||
document && (
|
||||
<Flex justify="center" auto>
|
||||
<Prompt
|
||||
when={document.hasPendingChanges}
|
||||
message={DISCARD_CHANGES}
|
||||
/>
|
||||
<Editor
|
||||
key={`${document.id}-${document.revision}`}
|
||||
text={document.text}
|
||||
emoji={document.emoji}
|
||||
onImageUploadStart={this.onImageUploadStart}
|
||||
onImageUploadStop={this.onImageUploadStop}
|
||||
onChange={this.onChange}
|
||||
onSave={this.onSave}
|
||||
onCancel={this.onDiscard}
|
||||
readOnly={!this.isEditing}
|
||||
/>
|
||||
<Actions
|
||||
align="center"
|
||||
justify="flex-end"
|
||||
readOnly={!this.isEditing}
|
||||
>
|
||||
{!isNew &&
|
||||
!this.isEditing && <Collaborators document={document} />}
|
||||
<Action>
|
||||
{this.isEditing ? (
|
||||
<SaveAction
|
||||
isSaving={this.isSaving}
|
||||
onClick={this.onSave.bind(this, true)}
|
||||
disabled={
|
||||
!(this.document && this.document.allowSave) ||
|
||||
this.isSaving
|
||||
}
|
||||
isNew={!!isNew}
|
||||
/>
|
||||
) : (
|
||||
<a onClick={this.onClickEdit}>Edit</a>
|
||||
)}
|
||||
</Action>
|
||||
{this.isEditing && (
|
||||
<Action>
|
||||
<a onClick={this.onDiscard}>Discard</a>
|
||||
</Action>
|
||||
)}
|
||||
{!this.isEditing && (
|
||||
<Action>
|
||||
<DocumentMenu document={document} />
|
||||
</Action>
|
||||
)}
|
||||
{!this.isEditing && <Separator />}
|
||||
<Action>
|
||||
{!this.isEditing && (
|
||||
<a onClick={this.onClickNew}>
|
||||
<NewDocumentIcon />
|
||||
</a>
|
||||
)}
|
||||
</Action>
|
||||
</Actions>
|
||||
</Flex>
|
||||
)}
|
||||
</ErrorBoundary>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user