File tree Expand file tree Collapse file tree 4 files changed +41
-1
lines changed
Expand file tree Collapse file tree 4 files changed +41
-1
lines changed Original file line number Diff line number Diff line change 55### Fixes
66
77- Use correct set-cookie for the HTTP Client response object ([ #2326 ] ( https://github.com/getsentry/sentry-java/pull/2326 ) )
8+ - Fix NoSuchElementException in CircularFifoQueue when cloning a Scope ([ #2328 ] ( https://github.com/getsentry/sentry-java/pull/2328 ) )
89
910### Features
1011
Original file line number Diff line number Diff line change @@ -97,7 +97,7 @@ public Scope(final @NotNull SentryOptions options) {
9797 this .fingerprint = new ArrayList <>(scope .fingerprint );
9898 this .eventProcessors = new CopyOnWriteArrayList <>(scope .eventProcessors );
9999
100- final Queue < Breadcrumb > breadcrumbsRef = scope .breadcrumbs ;
100+ final Breadcrumb [] breadcrumbsRef = scope .breadcrumbs . toArray ( new Breadcrumb [ 0 ]) ;
101101
102102 Queue <Breadcrumb > breadcrumbsClone = createBreadcrumbsList (scope .options .getMaxBreadcrumbs ());
103103
Original file line number Diff line number Diff line change @@ -131,4 +131,18 @@ public E remove() {
131131 return decorated ().remove ();
132132 }
133133 }
134+
135+ @ Override
136+ public Object [] toArray () {
137+ synchronized (lock ) {
138+ return decorated ().toArray ();
139+ }
140+ }
141+
142+ @ Override
143+ public <T > T [] toArray (T [] object ) {
144+ synchronized (lock ) {
145+ return decorated ().toArray (object );
146+ }
147+ }
134148}
Original file line number Diff line number Diff line change @@ -217,6 +217,31 @@ class ScopeTest {
217217 assertTrue(clone.attachments is CopyOnWriteArrayList )
218218 }
219219
220+ @Test
221+ fun `copying scope won't crash if there are concurrent operations` () {
222+ val options = SentryOptions ().apply {
223+ maxBreadcrumbs = 10000
224+ }
225+ val scope = Scope (options)
226+ for (i in 0 until options.maxBreadcrumbs) {
227+ scope.addBreadcrumb(Breadcrumb .info(" item" ))
228+ }
229+
230+ // remove one breadcrumb after the other on an extra thread
231+ Thread ({
232+ while (scope.breadcrumbs.isNotEmpty()) {
233+ scope.breadcrumbs.remove()
234+ }
235+ }, " thread-breadcrumb-remover" ).start()
236+
237+ // clone in the meantime
238+ while (scope.breadcrumbs.isNotEmpty()) {
239+ Scope (scope)
240+ }
241+
242+ // expect no exception to be thrown ¯\_(ツ)_/¯
243+ }
244+
220245 @Test
221246 fun `clear scope resets scope to default state` () {
222247 val scope = Scope (SentryOptions ())
You can’t perform that action at this time.
0 commit comments