From 42351704681c2c8dbad2795ef4846ec0c9ab4b8a Mon Sep 17 00:00:00 2001 From: Adam Cronin Date: Tue, 8 Aug 2023 17:03:46 -0400 Subject: [PATCH 1/6] Adding name prop to ErrorBoundary and sending as an attribute so users can distinguish between multiple --- packages/react/src/ErrorBoundary.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react/src/ErrorBoundary.tsx b/packages/react/src/ErrorBoundary.tsx index 2348a6fc..2f12fd55 100644 --- a/packages/react/src/ErrorBoundary.tsx +++ b/packages/react/src/ErrorBoundary.tsx @@ -7,6 +7,7 @@ type RenderFallback = () => ReactElement; export interface Props { children: ReactNode; fallback?: ReactElement | RenderFallback; + name: string; } export interface State { @@ -32,7 +33,8 @@ export class ErrorBoundary extends Component { } public async componentDidCatch(error: Error, info: ErrorInfo) { - const report = new BacktraceReport(error); + const { name } = this.props; + const report = new BacktraceReport(error, { 'errorboundary.name': name }); report.addStackTrace(this.COMPONENT_THREAD_NAME, info.componentStack); await this._client.send(report); } From 3b4aba4292f0d3eba4c076cf269446f9067d0ad1 Mon Sep 17 00:00:00 2001 From: Adam Cronin Date: Tue, 8 Aug 2023 17:04:46 -0400 Subject: [PATCH 2/6] Changing min supported version of React to 16.8.0 (hooks) and adding webpack, webpack-cli, and ts-loader to package.json --- package-lock.json | 35 +++++++++++++++++++++++++---------- packages/react/package.json | 7 +++++-- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index d87c04f2..084d0146 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10431,9 +10431,10 @@ } }, "node_modules/ts-loader": { - "version": "9.4.3", + "version": "9.4.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz", + "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", @@ -11230,8 +11231,9 @@ } }, "node_modules/webpack": { - "version": "5.87.0", - "license": "MIT", + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -11770,8 +11772,9 @@ }, "node_modules/webpack-cli": { "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, - "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -12272,10 +12275,13 @@ "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "ts-jest": "^29.1.1", - "typescript": "^5.0.4" + "ts-loader": "^9.4.4", + "typescript": "^5.0.4", + "webpack": "^5.88.2", + "webpack-cli": "^5.1.4" }, "peerDependencies": { - "react": ">=16.14.0" + "react": ">=16.8.0" } }, "packages/sdk-core": { @@ -12845,7 +12851,10 @@ "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "ts-jest": "^29.1.1", - "typescript": "^5.0.4" + "ts-loader": "^9.4.4", + "typescript": "^5.0.4", + "webpack": "^5.88.2", + "webpack-cli": "^5.1.4" } }, "@backtrace/rollup-plugin": { @@ -19357,7 +19366,9 @@ } }, "ts-loader": { - "version": "9.4.3", + "version": "9.4.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz", + "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -19881,7 +19892,9 @@ "dev": true }, "webpack": { - "version": "5.87.0", + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -20274,6 +20287,8 @@ }, "webpack-cli": { "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", diff --git a/packages/react/package.json b/packages/react/package.json index c4a3f42c..be402d5d 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -37,9 +37,12 @@ "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "ts-jest": "^29.1.1", - "typescript": "^5.0.4" + "ts-loader": "^9.4.4", + "typescript": "^5.0.4", + "webpack": "^5.88.2", + "webpack-cli": "^5.1.4" }, "peerDependencies": { - "react": ">=16.14.0" + "react": ">=16.8.0" } } From afa967ca4fd3c06603666c0dd1af06d135413f0c Mon Sep 17 00:00:00 2001 From: Adam Cronin Date: Tue, 8 Aug 2023 17:18:10 -0400 Subject: [PATCH 3/6] Adding an Inner ErrorBoundary to the react example app --- examples/sdk/react/src/App.tsx | 9 +++++++-- .../react/src/components/ButtonWithError.tsx | 20 +++++++++++++++++++ .../react/src/{ => components}/Fallback.tsx | 7 ++++--- .../react/src/components/InnerFallback.tsx | 9 +++++++++ examples/sdk/react/src/index.tsx | 4 ++-- 5 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 examples/sdk/react/src/components/ButtonWithError.tsx rename examples/sdk/react/src/{ => components}/Fallback.tsx (81%) create mode 100644 examples/sdk/react/src/components/InnerFallback.tsx diff --git a/examples/sdk/react/src/App.tsx b/examples/sdk/react/src/App.tsx index 0e75093b..e7df5897 100644 --- a/examples/sdk/react/src/App.tsx +++ b/examples/sdk/react/src/App.tsx @@ -1,9 +1,11 @@ import React, { useState } from 'react'; import './App.css'; -import { BacktraceClient } from '@backtrace/react'; +import { BacktraceClient, ErrorBoundary } from '@backtrace/react'; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import { SUBMISSION_URL } from './consts'; +import InnerFallback from './components/InnerFallback'; +import ButtonWithError from './components/ButtonWithError'; function App() { const [clicked, setClicked] = useState(false); @@ -50,8 +52,11 @@ function App() {

+ }> + + diff --git a/examples/sdk/react/src/components/ButtonWithError.tsx b/examples/sdk/react/src/components/ButtonWithError.tsx new file mode 100644 index 00000000..bdafa489 --- /dev/null +++ b/examples/sdk/react/src/components/ButtonWithError.tsx @@ -0,0 +1,20 @@ +import { useState } from 'react'; + +export default function ButtonWithError() { + const [clicked, setClicked] = useState(false); + + function throwOnClicked() { + if (clicked) { + throw new Error('Test throw in ButtonWithBoundary to demonstrate an Inner Error Boundary'); + } + } + + return ( + <> + {throwOnClicked()} + + + ); +} diff --git a/examples/sdk/react/src/Fallback.tsx b/examples/sdk/react/src/components/Fallback.tsx similarity index 81% rename from examples/sdk/react/src/Fallback.tsx rename to examples/sdk/react/src/components/Fallback.tsx index a7fe9fb3..103f82a3 100644 --- a/examples/sdk/react/src/Fallback.tsx +++ b/examples/sdk/react/src/components/Fallback.tsx @@ -1,6 +1,6 @@ -import './App.css'; +import '../App.css'; -export function Fallback() { +export default function Fallback() { return (
@@ -10,7 +10,8 @@ export function Fallback() { alt="Sauce Labs" />

- This is the fallback component that gets rendered after a rendering error! + This is the fallback component that gets rendered after a rendering error within the main + ErrorBoundary!

Check your Backtrace console to see the Error and Component stacks!

diff --git a/examples/sdk/react/src/components/InnerFallback.tsx b/examples/sdk/react/src/components/InnerFallback.tsx new file mode 100644 index 00000000..4c46abd7 --- /dev/null +++ b/examples/sdk/react/src/components/InnerFallback.tsx @@ -0,0 +1,9 @@ +import { useEffect } from 'react'; +import { toast } from 'react-toastify'; + +export default function InnerFallback() { + useEffect(() => { + toast('Inner ErrorBoundary Triggered! Check your Backtrace console to see the Error and Component stacks.'); + }); + return null; +} diff --git a/examples/sdk/react/src/index.tsx b/examples/sdk/react/src/index.tsx index fdcf8b84..f3724af1 100644 --- a/examples/sdk/react/src/index.tsx +++ b/examples/sdk/react/src/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import { ErrorBoundary, BacktraceClient } from '@backtrace/react'; -import { Fallback } from './Fallback'; +import Fallback from './components/Fallback'; import { SUBMISSION_URL } from './consts'; BacktraceClient.initialize({ @@ -21,7 +21,7 @@ BacktraceClient.initialize({ const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); root.render( - }> + }> , From 1c30aa0cedbd785d903950caf1a227283ea416aa Mon Sep 17 00:00:00 2001 From: Adam Cronin Date: Tue, 8 Aug 2023 17:26:09 -0400 Subject: [PATCH 4/6] Adding error.type when sending via the ErrorBoundary --- packages/react/src/ErrorBoundary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/ErrorBoundary.tsx b/packages/react/src/ErrorBoundary.tsx index 2f12fd55..863f3cf1 100644 --- a/packages/react/src/ErrorBoundary.tsx +++ b/packages/react/src/ErrorBoundary.tsx @@ -34,7 +34,7 @@ export class ErrorBoundary extends Component { public async componentDidCatch(error: Error, info: ErrorInfo) { const { name } = this.props; - const report = new BacktraceReport(error, { 'errorboundary.name': name }); + const report = new BacktraceReport(error, { 'errorboundary.name': name, 'error.type': 'Rendering error' }); report.addStackTrace(this.COMPONENT_THREAD_NAME, info.componentStack); await this._client.send(report); } From 4bed35559fa26823759fcedb02bc0c55b5a24994 Mon Sep 17 00:00:00 2001 From: Adam Cronin Date: Tue, 8 Aug 2023 17:30:38 -0400 Subject: [PATCH 5/6] Changing the ErrorBoundary name to be optional with a default --- packages/react/src/ErrorBoundary.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/react/src/ErrorBoundary.tsx b/packages/react/src/ErrorBoundary.tsx index 863f3cf1..9355f6a7 100644 --- a/packages/react/src/ErrorBoundary.tsx +++ b/packages/react/src/ErrorBoundary.tsx @@ -7,7 +7,7 @@ type RenderFallback = () => ReactElement; export interface Props { children: ReactNode; fallback?: ReactElement | RenderFallback; - name: string; + name?: string; } export interface State { @@ -34,7 +34,10 @@ export class ErrorBoundary extends Component { public async componentDidCatch(error: Error, info: ErrorInfo) { const { name } = this.props; - const report = new BacktraceReport(error, { 'errorboundary.name': name, 'error.type': 'Rendering error' }); + const report = new BacktraceReport(error, { + 'errorboundary.name': name ?? 'main', + 'error.type': 'Rendering error', + }); report.addStackTrace(this.COMPONENT_THREAD_NAME, info.componentStack); await this._client.send(report); } From 550f5dbbc69082eb658cfeeeb8c7bbc63d526a84 Mon Sep 17 00:00:00 2001 From: Adam Cronin Date: Wed, 9 Aug 2023 10:24:36 -0400 Subject: [PATCH 6/6] Updating error.type in ErrorBoundary --- packages/react/src/ErrorBoundary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/ErrorBoundary.tsx b/packages/react/src/ErrorBoundary.tsx index 9355f6a7..0e6bfb14 100644 --- a/packages/react/src/ErrorBoundary.tsx +++ b/packages/react/src/ErrorBoundary.tsx @@ -36,7 +36,7 @@ export class ErrorBoundary extends Component { const { name } = this.props; const report = new BacktraceReport(error, { 'errorboundary.name': name ?? 'main', - 'error.type': 'Rendering error', + 'error.type': 'Unhandled exception', }); report.addStackTrace(this.COMPONENT_THREAD_NAME, info.componentStack); await this._client.send(report);