Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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