Skip to content

Commit

Permalink
feat: Allow to pass errorHandler as record option (#1107)
Browse files Browse the repository at this point in the history
* feat: Allow to pass `errorHandler` as record option

* add docs

* Apply formatting changes
  • Loading branch information
mydea authored Mar 22, 2023
1 parent d2582e9 commit a225d8e
Show file tree
Hide file tree
Showing 7 changed files with 922 additions and 314 deletions.
5 changes: 5 additions & 0 deletions .changeset/pretty-plums-rescue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'rrweb': minor
---

feat: Allow to pass `errorHandler` as record option
1 change: 1 addition & 0 deletions guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ The parameter of `rrweb.record` accepts the following options.
| collectFonts | false | whether to collect fonts in the website |
| userTriggeredOnInput | false | whether to add `userTriggered` on input events that indicates if this event was triggered directly by the user or not. [What is `userTriggered`?](https://github.com/rrweb-io/rrweb/pull/495) |
| plugins | [] | load plugins to provide extended record functions. [What is plugins?](./docs/recipes/plugin.md) |
| errorHandler | - | A callback that is called if something inside of rrweb throws an error. The callback receives the error as argument. |

#### Privacy

Expand Down
36 changes: 36 additions & 0 deletions packages/rrweb/src/record/error-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { ErrorHandler } from '../types';

type Callback = (...args: unknown[]) => unknown;

let errorHandler: ErrorHandler | undefined;

export function registerErrorHandler(handler: ErrorHandler | undefined) {
errorHandler = handler;
}

export function unregisterErrorHandler() {
errorHandler = undefined;
}

/**
* Wrap callbacks in a wrapper that allows to pass errors to a configured `errorHandler` method.
*/
export const callbackWrapper = <T extends Callback>(cb: T): T => {
if (!errorHandler) {
return cb;
}

const rrwebWrapped = ((...rest: unknown[]) => {
try {
return cb(...rest);
} catch (error) {
if (errorHandler && errorHandler(error) === true) {
return;
}

throw error;
}
}) as unknown as T;

return rrwebWrapped;
};
11 changes: 10 additions & 1 deletion packages/rrweb/src/record/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ import { IframeManager } from './iframe-manager';
import { ShadowDomManager } from './shadow-dom-manager';
import { CanvasManager } from './observers/canvas/canvas-manager';
import { StylesheetManager } from './stylesheet-manager';
import {
callbackWrapper,
registerErrorHandler,
unregisterErrorHandler,
} from './error-handler';

function wrapEvent(e: event): eventWithTime {
return {
Expand Down Expand Up @@ -85,8 +90,11 @@ function record<T = eventWithTime>(
plugins,
keepIframeSrcFn = () => false,
ignoreCSSAttributes = new Set([]),
errorHandler,
} = options;

registerErrorHandler(errorHandler);

const inEmittingFrame = recordCrossOriginIframes
? window.parent === window
: true;
Expand Down Expand Up @@ -416,7 +424,7 @@ function record<T = eventWithTime>(
const handlers: listenerHandler[] = [];

const observe = (doc: Document) => {
return initObservers(
return callbackWrapper(initObservers)(
{
mutationCb: wrappedMutationEmit,
mousemoveCb: (positions, source) =>
Expand Down Expand Up @@ -609,6 +617,7 @@ function record<T = eventWithTime>(
return () => {
handlers.forEach((h) => h());
recording = false;
unregisterErrorHandler();
};
} catch (error) {
// TODO: handle internal error
Expand Down
Loading

0 comments on commit a225d8e

Please sign in to comment.