@sentry/react error boundary eventId does not match event id sent by Sentry's network request in development mode; has reproduction
cheapsteak opened this issue · 8 comments
Is there an existing issue for this?
- I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
- I have reviewed the documentation https://docs.sentry.io/
- I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases
How do you use Sentry?
Sentry Saas (sentry.io)
Which SDK are you using?
@sentry/react
SDK Version
7.54.0
Framework Version
17.0.2
Link to Sentry event
No response
SDK Setup
Sentry.init({
dsn: process.env.REACT_APP_DSN,
});
Steps to Reproduce
repro repo https://github.com/cheapsteak/sentry-error-boundary-bug-repro/tree/master
- Set environment variable REACT_APP_DSN
- Run the React app in development mode (
npm i
thennpm start
) - Pop open network tab
- Click the button to trigger an error
- Verify whether the "event_id" in the network tab matches the event id shown by the react component
Screen.Recording.2023-06-02.at.12.02.19.PM.mov
(this is an update of the reproduction previously provided by @cameronmcefee in #4534 (comment))
Expected Result
event id in network request should match what's shown on page
Actual Result
event id in network request is different from what's shown on page
Output
Hey Sorry for my poor highlighting skills but i got the pinpoint
Code Update
import React, { useState } from "react";
import * as Sentry from "@sentry/react";
Sentry.init({
dsn: "REPLACE_ DSN", // or use environment variable
});
function App() {
const [msg, setMsg] = useState({ text: "Works", eventId: null });
const handleClick = () => {
try {
throw new Error("This will break");
} catch (error) {
const eventId = Sentry.captureException(error);
setMsg({ text: "An error occurred", eventId });
}
};
return (
<Sentry.ErrorBoundary fallback={() => <div>Error occurred</div>}>
<div>{msg.text}</div>
{msg.eventId && (
<p>
Event ID: <code>{msg.eventId}</code>
</p>
)}
<button onClick={handleClick}>Click to trigger error</button>
</Sentry.ErrorBoundary>
);
}
export default App;
Justification
To fix the issue and display the actual event IDs generated by Sentry, I made the following changes to the code:
- Instead of using the uuid package to generate event IDs, I utilized the captureException method provided by @sentry/react. This method captures the exception and returns a promise that resolves to the actual Event object created by Sentry.
- I modified the handleClick function to be an asynchronous function. Within this function, I captured the exception using Sentry.captureException(error), and then I awaited the returned promise to get the actual Event object.
- I accessed the event_id property of the Event object (event.event_id) and included it in the msg state to display the event ID in the UI.
I hope this helps you !!!!! :)
Hmm, does that not just defeat the purpose of @sentry/react
's Sentry.ErrorBoundary
?
True, But I think capturing exceptions is the correct method because
The event ID is not directly accessible within the Sentry.ErrorBoundary component without using captureException or a similar method. The event ID is typically generated and sent to Sentry when an error is captured and reported.
If you specifically need to retrieve the event ID upon a button click, you would need to use the captureException method or a similar mechanism to capture the error and retrieve the event ID.
I maybe wrong here please correct me !!
The event ID is not directly accessible within the Sentry.ErrorBoundary component without using captureException or a similar method.
eventId
is literally a prop passed into Sentry.ErrorBoundary's FallbackRender
..
.. the confidence with which that was stated reminds me of ... are you trying to solve this with chatgpt? worth a shot, but the bug that needs to be fixed / code that needs to change is on the library's end
Hey, this is just a problem in react development mode. In development mode, react will rethrow errors inside an error boundary causing different event IDs to be shown. Please build your app with production mode and everything should work as expected (I also confirmed this with your repro app).
:nod: thank you, updated issue title to acknowledge this only affects development mode 🙏
I imagine this is still not desired behaviour in dev mode since the doc says "In development mode, React will rethrow errors caught within an error boundary. This will result in errors being reported twice to Sentry with the above setup", which sounds like it's saying "duplicate errors will be sent" and not "eventId will be unreliable"? (we did update our error boundary's messaging in dev mode but not before having a few folks trip on it)
@cheapsteak I fully agree with you. We need to look at this again, and try and understand what's going on here and make the docs more clear.
If I remember correctly captureException
is internally called twice in development mode, but the dedupe integration throws away the second one. However, since we called captureException
twice, we pass the second event ID to the error boundary (which is not the one that was reported).
Updated the docs here: getsentry/sentry-docs#9610