Fix: Breadcrumbs added on forked context are now captured#629
Fix: Breadcrumbs added on forked context are now captured#629lucas-zimerman wants to merge 14 commits intomainfrom
Conversation
…version. Added tests. used a better name for the new function that joins two groups of breadcrumbs. Removed comment from java layer. Removed duplicated tests on the wrapper test file
| } | ||
| }); | ||
|
|
||
| describe('Device Context Breadcrumb filter', () => { |
There was a problem hiding this comment.
We should add test for user set timeout timestamp. Something like this:
const jsList = [
{ timestamp: 2, message: 'new js' },
{ timestamp: 1, message: 'new js' },
] as Breadcrumb[];
const nativeList = [
{ timestamp: 2, message: 'new native' },
{ timestamp: 2, message: 'new js' },
{ timestamp: 1, message: 'new js' },
{ timestamp: 3, message: 'new native' },
] as Breadcrumb[];
const expected = [
{ timestamp: 2, message: 'new native' },
{ timestamp: 2, message: 'new js' },
{ timestamp: 1, message: 'new js' },
{ timestamp: 3, message: 'new native' },
] as Breadcrumb[];|
This pull request has gone three weeks without activity. In another week, I will close it. But! If you comment or otherwise update it, I will reset the clock, and if you label it "A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀 |
…ue; requested changes
| catch (Throwable e) { | ||
| final String errorMessage ="Error while capturing envelope"; | ||
| logger.log(Level.WARNING, errorMessage); | ||
| call.reject(errorMessage); |
There was a problem hiding this comment.
I see previously this was call.reject(String.valueOf(e));? Does this change the error in any way?
|
|
||
| private static final ILogger logger = new AndroidLogger(NAME); | ||
|
|
||
| public static Object convertToWritable(Object serialized) { |
There was a problem hiding this comment.
Can this return JSObject directly?
| import io.sentry.SentryLevel; | ||
| import io.sentry.android.core.AndroidLogger; | ||
|
|
||
| public class CapSentryMapConverter { |
There was a problem hiding this comment.
Can we add unit tests for this class?
| private _mergeUniqueBreadcrumbs(jsList: Breadcrumb[], nativeList: Breadcrumb[], maxBreadcrumbs: number): Breadcrumb[] { | ||
| // Ensure both lists are ordered by timestamp. | ||
| const orderedNativeList = [...nativeList].sort((a, b) => (a.timestamp ?? 0) - (b.timestamp ?? 0)); | ||
| const orderedJsList = [...jsList].sort((a, b) => (a.timestamp ?? 0) - (b.timestamp ?? 0)); | ||
|
|
||
| const combinedList: Breadcrumb[] = []; | ||
| let jsIndex = 0; | ||
| let natIndex = 0; | ||
|
|
||
| while (jsIndex < orderedJsList.length && natIndex < orderedNativeList.length && combinedList.length < maxBreadcrumbs) | ||
| { | ||
| const jsBreadcrumb = orderedJsList[jsIndex]; | ||
| const natBreadcrumb = orderedNativeList[natIndex]; | ||
|
|
||
| if (jsBreadcrumb.timestamp === natBreadcrumb.timestamp && | ||
| jsBreadcrumb.message === natBreadcrumb.message) { | ||
| combinedList.push(jsBreadcrumb); | ||
| jsIndex++; | ||
| natIndex++; | ||
| } | ||
| else if (jsBreadcrumb.timestamp && natBreadcrumb.timestamp && | ||
| jsBreadcrumb.timestamp < natBreadcrumb.timestamp) | ||
| { | ||
| combinedList.push(jsBreadcrumb); | ||
| jsIndex++; | ||
| } | ||
| else { | ||
| combinedList.push(natBreadcrumb); | ||
| natIndex++; | ||
| } | ||
| } | ||
|
|
||
| // Add remaining breadcrumbs from the JavaScript and Native list if space allows. | ||
| while (jsIndex < orderedJsList.length && combinedList.length < maxBreadcrumbs) { | ||
| combinedList.push(orderedJsList[jsIndex++]); | ||
| } | ||
|
|
||
| while (natIndex < orderedNativeList.length && combinedList.length < maxBreadcrumbs) { | ||
| combinedList.push(orderedNativeList[natIndex++]); | ||
| } | ||
| return combinedList; | ||
| } |
There was a problem hiding this comment.
The function works, but I think we should consider marking the JS crumbs during the creation on native layers, as then we can also filter then on the native layers and only return the native crumbs.
The native solution would be faster and required less memory.
We could do JSBreadcrumb extends Breadcrumb and then filter breadcrumb instanceof JSBreadcrumb.
There was a problem hiding this comment.
Because Breadcrumb is final (https://github.com/getsentry/sentry-java/blob/9596bb93199a1032cb255a62bea32020bd04c9ac/sentry/src/main/java/io/sentry/Breadcrumb.java#L20), thank @lucas-zimerman for pointing that out, we can extend it.
But the class has property called unknown marked for internal use. We could add a flag to it.
Breadcrumb crumb = new Breadcrumb();
crumb.getUnknown().put("hybrid", true);@romtsn @markushi I don't know current usage of the unknown field, could this cause any issue/would it work?
There was a problem hiding this comment.
unknown is used across our protocol classes to store attributes which are not defined within sentry-native. This avoids any data loss, achieving ~serialize(deserialize(breadcrumbJson)) == breadcrumbJson.
There was a problem hiding this comment.
So yes it would work, but all unknown fields end up in the network requests as well - which is probably something we want to have anyway at some point?
To be honest I'd prefer some explicit field, e.g. breadcrumb.origin.
There was a problem hiding this comment.
Got it thanks, breadcrumb.origin at first I think it could be runtime only, not included in the serialization, not transferred over network. I can see it being used later in the product, but currently there are no plans and there might never be.
We only want to solve a technical problem of efficiently filter js breadcrumbs from all the crumbs currently present on the scope.
There was a problem hiding this comment.
yeah, let's please not use unknown - it exists to work-around JVM's static type system exclusively. A new field is the cleanest way imo, but we could also open the Breadcrumb class for extension, should not be a problem
There was a problem hiding this comment.
I also like the idea of breadcrumb.origin, it could also help in the future to know if a breadcrumb was originated from the JavaScript layer or native
There was a problem hiding this comment.
I also like the idea of breadcrumb.origin, it could also help in the future to know if a breadcrumb was originated from the JavaScript layer or native
Hey @lucas-zimerman 👋
I've drafted an iOS PR and was wondering if you have any early feedback on it. Does the approach chosen unblock this PR?
There was a problem hiding this comment.
It surelly does thank you!
Co-authored-by: Krystof Woldrich <[email protected]>
|
This pull request has gone three weeks without activity. In another week, I will close it. But! If you comment or otherwise update it, I will reset the clock, and if you label it "A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀 |
|
This pull request has gone three weeks without activity. In another week, I will close it. But! If you comment or otherwise update it, I will reset the clock, and if you label it "A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀 |
|
This pull request has gone three weeks without activity. In another week, I will close it. But! If you comment or otherwise update it, I will reset the clock, and if you label it "A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀 |
|
This pull request has gone three weeks without activity. In another week, I will close it. But! If you comment or otherwise update it, I will reset the clock, and if you label it "A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀 |
|
This pull request has gone three weeks without activity. In another week, I will close it. But! If you comment or otherwise update it, I will reset the clock, and if you label it "A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀 |
This PR brings more native context data to be synced with captured events and also allows hint breadcrumbs to be properly registered, for example:
will now be registered on the event, including the native events:

Additional notes on the PR:
🛑 Blocked by
breadrumb.originsentry-java#3470breadrumb.originsentry-cocoa#4043Closes #263