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.
84 lines
2.1 KiB
84 lines
2.1 KiB
import React from 'react';
|
|
import type { ReactNode } from 'react';
|
|
import { warning, error } from '../../dev-warning';
|
|
import { noop } from '../../empty';
|
|
import bindEvents from '../event-bindings/bind-events';
|
|
import { RbdInvariant } from '../../invariant';
|
|
import type { AppCallbacks } from './drag-drop-context-types';
|
|
|
|
interface Props {
|
|
children: (setCallbacks: (callbacks: AppCallbacks) => void) => ReactNode;
|
|
}
|
|
|
|
export default class ErrorBoundary extends React.Component<Props> {
|
|
callbacks: AppCallbacks | null = null;
|
|
unbind: () => void = noop;
|
|
|
|
componentDidMount() {
|
|
this.unbind = bindEvents(window, [
|
|
{
|
|
eventName: 'error',
|
|
fn: this.onWindowError,
|
|
},
|
|
]);
|
|
}
|
|
|
|
componentDidCatch(err: Error) {
|
|
if (err instanceof RbdInvariant) {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
error(err.message);
|
|
}
|
|
|
|
this.setState({});
|
|
return;
|
|
}
|
|
|
|
// throwing error for other error boundaries
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
throw err;
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.unbind();
|
|
}
|
|
|
|
onWindowError = (event: ErrorEvent) => {
|
|
const callbacks: AppCallbacks = this.getCallbacks();
|
|
|
|
if (callbacks.isDragging()) {
|
|
callbacks.tryAbort();
|
|
warning(`
|
|
An error was caught by our window 'error' event listener while a drag was occurring.
|
|
The active drag has been aborted.
|
|
`);
|
|
}
|
|
|
|
const err: Error | null = event.error;
|
|
|
|
if (err instanceof RbdInvariant) {
|
|
// Marking the event as dealt with.
|
|
// This will prevent any 'uncaught' error warnings in the console
|
|
event.preventDefault();
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
error(err.message);
|
|
}
|
|
}
|
|
};
|
|
|
|
getCallbacks = (): AppCallbacks => {
|
|
if (!this.callbacks) {
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
throw new Error('Unable to find AppCallbacks in <ErrorBoundary/>');
|
|
}
|
|
return this.callbacks;
|
|
};
|
|
|
|
setCallbacks = (callbacks: AppCallbacks) => {
|
|
this.callbacks = callbacks;
|
|
};
|
|
|
|
render() {
|
|
return this.props.children(this.setCallbacks);
|
|
}
|
|
}
|