Skip to content

♻️ React- Replace addEvent for AddError, Export Error Boundary#4317

Merged
BeltranBulbarellaDD merged 5 commits intomainfrom
beltran.bulbarella/refactor_react_errors
Mar 16, 2026
Merged

♻️ React- Replace addEvent for AddError, Export Error Boundary#4317
BeltranBulbarellaDD merged 5 commits intomainfrom
beltran.bulbarella/refactor_react_errors

Conversation

@BeltranBulbarellaDD
Copy link
Copy Markdown
Contributor

@BeltranBulbarellaDD BeltranBulbarellaDD commented Mar 12, 2026

Motivation

The addReactError function was building and dispatching a raw RUM error event directly, duplicating logic already handled by addError in rum-core.
Additionally, ErrorBoundary was not composable, there was no way to create a customised error boundary that reports errors through a different mechanism (e.g. for the upcoming Next.js integration)

The idea is to refactor addReactError and ErrorBoundary without changing functionality.

Changes

  • reactPlugin.ts: replaced addEvent with addError as the value passed to onRumStart subscribers, react plugin no longer needs access to the raw event API
  • addReactError.ts: simplified to delegate directly to addError(), removing the manual computeRawError / event construction
  • errorBoundary.ts: introduced BaseErrorBoundary abstract class and createErrorBoundary(reportError, displayName) factory, so error boundaries can be composed with any error-reporting callback; ErrorBoundary now extends BaseErrorBoundary
  • error/index.ts: exported createErrorBoundary
  • Added src/entries/errorBoundary.ts entry point and error-boundary/package.json for the @datadog/browser-rum-react/error-boundary subpath export
  • Updated initializeReactPlugin test helper and all affected specs accordingly

Usage of the changes in Error Boundary can be seen here

Test instructions

Old unit and e2e test should pass.
Added extra validation unit and e2e tests for the new addError function.

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

@BeltranBulbarellaDD BeltranBulbarellaDD changed the title Replace addEvent with addError, add error boundary entry point. ♻️ React- Replace addEvent for AddError, Export Error Boundary Mar 12, 2026
@datadog-datadog-prod-us1-2
Copy link
Copy Markdown

datadog-datadog-prod-us1-2 bot commented Mar 12, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 90.48%
Overall Coverage: 77.24% (+0.03%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 8576067 | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da bot commented Mar 12, 2026

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 175.00 KiB 175.02 KiB +20 B +0.01%
Rum Profiler 6.16 KiB 6.16 KiB 0 B 0.00%
Rum Recorder 27.46 KiB 27.46 KiB 0 B 0.00%
Logs 56.80 KiB 56.80 KiB 0 B 0.00%
Flagging 944 B 944 B 0 B 0.00%
Rum Slim 130.64 KiB 130.66 KiB +20 B +0.01%
Worker 23.63 KiB 23.63 KiB 0 B 0.00%
🚀 CPU Performance
Action Name Base CPU Time (ms) Local CPU Time (ms) 𝚫%
RUM - add global context 0.0046 0.0053 +15.22%
RUM - add action 0.0127 0.017 +33.86%
RUM - add error 0.0135 0.0172 +27.41%
RUM - add timing 0.0025 0.0038 +52.00%
RUM - start view 0.0122 0.0132 +8.20%
RUM - start/stop session replay recording 0.0007 0.0008 +14.29%
Logs - log message 0.0144 0.0166 +15.28%
🧠 Memory Performance
Action Name Base Memory Consumption Local Memory Consumption 𝚫
RUM - add global context 27.37 KiB 26.56 KiB -832 B
RUM - add action 53.07 KiB 52.69 KiB -390 B
RUM - add timing 25.97 KiB 27.01 KiB +1.04 KiB
RUM - add error 55.69 KiB 53.63 KiB -2.06 KiB
RUM - start/stop session replay recording 25.52 KiB 26.97 KiB +1.45 KiB
RUM - start view 462.52 KiB 462.45 KiB -76 B
Logs - log message 44.79 KiB 45.39 KiB +610 B

🔗 RealWorld

@BeltranBulbarellaDD BeltranBulbarellaDD marked this pull request as ready for review March 12, 2026 14:30
@BeltranBulbarellaDD BeltranBulbarellaDD requested a review from a team as a code owner March 12, 2026 14:30
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 32bdcc7216

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +61 to +69
const DatadogErrorBoundary: React.ComponentClass<ErrorBoundaryProps> = class DatadogErrorBoundary extends BaseErrorBoundary {
protected reportError(error: Error, errorInfo: ErrorInfo) {
reportError(error, errorInfo)
}
}

DatadogErrorBoundary.displayName = displayName

return DatadogErrorBoundary
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 suggestion: ‏We could remove some complexity by returning the class directly from here. What do you think?

Suggested change
const DatadogErrorBoundary: React.ComponentClass<ErrorBoundaryProps> = class DatadogErrorBoundary extends BaseErrorBoundary {
protected reportError(error: Error, errorInfo: ErrorInfo) {
reportError(error, errorInfo)
}
}
DatadogErrorBoundary.displayName = displayName
return DatadogErrorBoundary
export function createErrorBoundary(
reportError: (error: Error, errorInfo: ErrorInfo) => void,
displayName = 'ErrorBoundary'
) {
const DatadogErrorBoundary: React.ComponentClass<ErrorBoundaryProps> = class extends React.Component<
ErrorBoundaryProps,
State
> {
constructor(props: ErrorBoundaryProps) {
super(props)
this.state = INITIAL_STATE
}
static getDerivedStateFromError(error: Error): State {
return { didCatch: true, error }
}
resetError = () => {
this.setState(INITIAL_STATE)
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
reportError(error, errorInfo)
}
render() {
if (this.state.didCatch) {
return React.createElement(this.props.fallback, {
error: this.state.error,
resetError: this.resetError,
})
}
return this.props.children
}
}
DatadogErrorBoundary.displayName = displayName
return DatadogErrorBoundary
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm I don't think it's possible as CallExpression can have side effects when the module is evaluated. Maybe move it in a function declaration?. This way createErrorBoundary(addReactError) can break tree-shaking. WDYT? Should we keep it?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove that function. Export the BaseErrorBoundary class and extend it like you do below.

Comment on lines +61 to +69
const DatadogErrorBoundary: React.ComponentClass<ErrorBoundaryProps> = class DatadogErrorBoundary extends BaseErrorBoundary {
protected reportError(error: Error, errorInfo: ErrorInfo) {
reportError(error, errorInfo)
}
}

DatadogErrorBoundary.displayName = displayName

return DatadogErrorBoundary
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove that function. Export the BaseErrorBoundary class and extend it like you do below.

@BeltranBulbarellaDD
Copy link
Copy Markdown
Contributor Author

@codex pls review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

protected abstract reportError(error: Error, errorInfo: ErrorInfo): void
}

export function createErrorBoundary(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relevant to the open discussion about exporting BaseErrorBoundary for direct extension: React explicitly recommends against component inheritance hierarchies — "we haven't found any use cases where we would recommend creating component inheritance hierarchies". Might be worth factoring that in when deciding which API to ship.

Copy link
Copy Markdown
Contributor

@mormubis mormubis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The design question around BaseErrorBoundary vs createErrorBoundary it's important. Left a comment with some relevant context.

@BeltranBulbarellaDD BeltranBulbarellaDD merged commit fcfa906 into main Mar 16, 2026
21 checks passed
@BeltranBulbarellaDD BeltranBulbarellaDD deleted the beltran.bulbarella/refactor_react_errors branch March 16, 2026 09:59
@github-actions github-actions bot locked and limited conversation to collaborators Mar 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants