Editor opens normally
💥
The crash seems to be related to an early network call from here:
https://github.com/wordpress-mobile/WordPress-iOS/blob/9f2a606159efaaea4d8caec5332f761a88140ee1/WordPress/Classes/Stores/EditorThemeStore.swift#L102
The app decided to make the request as a Self Hosted site and ends up crashing here:
While trying to get the Rest API object.
I don't think it's a problem specific to the Editor Theme feature but pinging @chipsnyder just in case. There might be something wrong with the Blog object passed.
cc @pinarol
Thanks for reporting and the analysis @etoledom! Can you also attach the crash log?
Can you elaborate what you mean by "early" network call? Is there something like a state in the app which is too early to make a network call?
Crash log:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSRegularExpression enumerateMatchesInString:options:range:usingBlock:]: nil argument'
Thread backtrace:
frame #0: 0x00000001a4a3cbe0 libobjc.A.dylib`objc_exception_throw
frame #1: 0x00000001a502fc50 Foundation`-[NSRegularExpression(NSMatching) enumerateMatchesInString:options:range:usingBlock:] + 1856
frame #2: 0x00000001a5052748 Foundation`-[NSRegularExpression(NSMatching) matchesInString:options:range:] + 184
frame #3: 0x00000001a505c374 Foundation`-[NSRegularExpression(NSReplacement) stringByReplacingMatchesInString:options:range:withTemplate:] + 168
* frame #4: 0x0000000100c6c0f0 WordPress`-[Blog urlWithPath:](self=0x0000000283ff7f60, _cmd="urlWithPath:", path=@"wp-json/") at Blog.m:202:12
frame #5: 0x0000000101ac128c WordPress`apiBase(blog=0x0000000283ff7f60) at WordPressOrgRestApi+WordPress.swift:33:22
frame #6: 0x0000000101ac14f8 WordPress`WordPressOrgRestApi.init(blog=0x0000000283ff7f60) at WordPressOrgRestApi+WordPress.swift:38:29
frame #7: 0x0000000101ac198c WordPress`@objc WordPressOrgRestApi.init(blog:) at <compiler-generated>:0
frame #8: 0x0000000100c70898 WordPress`-[Blog wordPressOrgRestApi](self=0x0000000283ff7f60, _cmd="wordPressOrgRestApi") at Blog.m:724:32
frame #9: 0x000000010121d074 WordPress`GutenbergNetworkRequest.performSelfHostedRequest(completion=0x00000001011a7ee0 WordPress`partial apply forwarder for closure #1 (Swift.Result<Any, __C.NSError>) -> () in WordPress.EditorThemeStore.(fetchTheme in _97C339A53F625C50005B8CAC06D60566)(for: __C.Blog) -> () at <compiler-generated>, self=WordPress.GutenbergNetworkRequest @ 0x000000016f205748) at GutenbergNetworking.swift:44:30
frame #10: 0x000000010121bfcc WordPress`GutenbergNetworkRequest.selfHostedRequest(completion=0x00000001011a7ee0 WordPress`partial apply forwarder for closure #1 (Swift.Result<Any, __C.NSError>) -> () in WordPress.EditorThemeStore.(fetchTheme in _97C339A53F625C50005B8CAC06D60566)(for: __C.Blog) -> () at <compiler-generated>, self=WordPress.GutenbergNetworkRequest @ 0x000000016f205748) at GutenbergNetworking.swift:40:9
frame #11: 0x000000010121bd0c WordPress`GutenbergNetworkRequest.request(completion=0x00000001011a7ee0 WordPress`partial apply forwarder for closure #1 (Swift.Result<Any, __C.NSError>) -> () in WordPress.EditorThemeStore.(fetchTheme in _97C339A53F625C50005B8CAC06D60566)(for: __C.Blog) -> () at <compiler-generated>, self=WordPress.GutenbergNetworkRequest @ 0x000000016f205748) at GutenbergNetworking.swift:19:13
frame #12: 0x00000001011a53bc WordPress`EditorThemeStore.fetchTheme(blog=0x0000000283ff7f60, self=0x0000000283846260) at EditorThemeStore.swift:102:64
frame #13: 0x00000001011a51fc WordPress`closure #1 in EditorThemeStore.queriesChanged(query=WordPress.EditorThemeQuery @ 0x000000016f2057d8, self=0x0000000283846260) at EditorThemeStore.swift:89:13
frame #14: 0x00000001011a5410 WordPress`thunk for @callee_guaranteed (@guaranteed EditorThemeQuery) -> (@error @owned Error) at <compiler-generated>:0
frame #15: 0x00000001011a5470 WordPress`partial apply for thunk for @callee_guaranteed (@guaranteed EditorThemeQuery) -> (@error @owned Error) at <compiler-generated>:0
frame #16: 0x00000001b266535c libswiftCore.dylib`(extension in Swift):Swift.Sequence.forEach((A.Element) throws -> ()) throws -> () + 480
frame #17: 0x00000001011a5138 WordPress`EditorThemeStore.queriesChanged(self=0x0000000283846260) at EditorThemeStore.swift:88:23
frame #18: 0x00000001074dc8fc WordPressFlux`QueryStore.activeQueryReferences.didset(oldValue=1 value, self=0x0000000283846260) at QueryStore.swift:44:13
frame #19: 0x00000001074de18c WordPressFlux`QueryStore.activeQueryReferences.setter(value=2 values, self=0x0000000283846260) at QueryStore.swift:0
frame #20: 0x00000001074df130 WordPressFlux`QueryStore.query(query=WordPress.EditorThemeQuery @ 0x000000016f206090, self=0x0000000283846260) at QueryStore.swift:111:9
frame #21: 0x00000001014f5e68 WordPress`GutenbergViewController.fetchEditorTheme(self=0x000000013238aa00) at GutenbergViewController.swift:952:47
frame #22: 0x00000001014f5270 WordPress`GutenbergViewController.viewDidLoad(self=0x000000013238aa00) at GutenbergViewController.swift:321:9
The crash log is not very helpful, I think the key is the frame #10: Trying to perform a self-hosted request on a wpcom site.
Can you elaborate what you mean by "early" network call?
early as being a gutenberg related network call before the editor loaded. Then I noticed it's performed from viewDidLoad. I think this is fine 👍
Thanks for the ping @etoledom!
There might be something wrong with the Blog object passed.
I agree with your analysis to me it looks like the problem is probably related to the Blog object. We could probably add some null safety around that and that might help or maybe there needs to be a try catch around that NSRegularExpression call
FWIW, I ran into this today and found that blog.isAccessibleThroughWPCom() is returning false here:
https://github.com/wordpress-mobile/WordPress-iOS/blob/6476e0ea9141da1e0dd60fa84afd1c7d12b27c41/WordPress/Classes/ViewRelated/Gutenberg/GutenbergNetworking.swift#L16
because self.account is nil here:
https://github.com/wordpress-mobile/WordPress-iOS/blob/0a2ca4d11cf08310f0e0b1cd79a4e70cab8cbcc0/WordPress/Classes/Models/Blog.m#L731
I don't know why this is happening though.
Hey @guarani,
This ended up being the result of a retain-cycle. blog.isAccessibleThroughWPCom() is returning false because the blog object had faulted and was cleaned up by CoreData. Because GutenbergViewController was still in memory then activeQueries for the EditorThemeStore also remained in memory.
So adding a new query then triggered a new request against all of the other activeQueries that were holding bad Blog objects. Eliminating the retain cycle cleared it up. So now this scenario won't happen once we get this merged.
@chipsnyder Nice work tracking this bug back to the keyboard notification closures! Looks like a difficult one to catch.
I hadn't noticed the linked PR above, thanks for the explanation!
Did this issue got fixed by https://github.com/wordpress-mobile/WordPress-iOS/pull/14359, can we close @chipsnyder ?
Yup we can close this now. Thanks for catching this @hypest
I got a similar crash to this today:
2020-08-04 15:44:20.106311-0400 WordPress[95833:3404310] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSRegularExpression enumerateMatchesInString:options:range:usingBlock:]: nil argument'
after logging out as one user, logging in as another and then attempting to create a new post.
2020-08-04 15:44:20.048505-0400 WordPress[95833:3408223] Task.<29> finished with error [-1004] Error Domain=NSURLErrorDomain Code=-1004 "Could not connect to the server." UserInfo={NSUnderlyingError=0x7fb296ca2a70 {Error Domain=kCFErrorDomainCFNetwork Code=-1004 "(null)" UserInfo={_kCFStreamErrorCodeKey=61, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=http://localhost:8081/status, NSErrorFailingURLKey=http://localhost:8081/status, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=61, NSLocalizedDescription=Could not connect to the server.} 2020-08-04 15:44:20.106311-0400 WordPress[95833:3404310] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSRegularExpression enumerateMatchesInString:options:range:usingBlock:]: nil argument' *** First throw call stack: ( 0 CoreFoundation 0x00007fff23e3de6e __exceptionPreprocess + 350 1 libobjc.A.dylib 0x00007fff512539b2 objc_exception_throw + 48 2 Foundation 0x00007fff25a45320 -[NSRegularExpression(NSMatching) matchesInString:options:range:] + 0 3 Foundation 0x00007fff25a453b2 -[NSRegularExpression(NSMatching) matchesInString:options:range:] + 146 4 Foundation 0x00007fff25a457fd -[NSRegularExpression(NSReplacement) stringByReplacingMatchesInString:options:range:withTemplate:] + 176 5 WordPress 0x000000010bf67459 -[Blog urlWithPath:] + 345 6 WordPress 0x000000010ce512c5 $s9WordPress7apiBase33_27EC9C948CC854094B4492A03135FD18LL4blog10Foundation3URLVSgSo4BlogC_tF + 373 7 WordPress 0x000000010ce515c4 $s12WordPressKit0aB10OrgRestApiC0aB0E4blogACSgSo4BlogC_tcfc + 276 8 WordPress 0x000000010ce519f3 $s12WordPressKit0aB10OrgRestApiC0aB0E4blogACSgSo4BlogC_tcfcTo + 51 9 WordPress 0x000000010bf6bd09 -[Blog wordPressOrgRestApi] + 73 10 WordPress 0x000000010c542429 $s9WordPress23GutenbergNetworkRequestV017performSelfHostedE033_C5237879BCC4451BCD9D90EA1DA24FAALL10completionyys6ResultOyypSo7NSErrorCGc_tF + 153 11 WordPress 0x000000010c5413d8 $s9WordPress23GutenbergNetworkRequestV010selfHostedE033_C5237879BCC4451BCD9D90EA1DA24FAALL10completionyys6ResultOyypSo7NSErrorCGc_tF + 40 12 WordPress 0x000000010c541145 $s9WordPress23GutenbergNetworkRequestV7request10completionyys6ResultOyypSo7NSErrorCGc_tF + 341 13 WordPress 0x000000010c4c779e $s9WordPress16EditorThemeStoreC05fetchD033_97C339A53F625C50005B8CAC06D60566LL3forySo4BlogC_tF + 366 14 WordPress 0x000000010c4c7604 $s9WordPress16EditorThemeStoreC14queriesChangedyyFyAA0cD5QueryVXEfU_ + 68 15 WordPress 0x000000010c4c77f2 $s9WordPress16EditorThemeQueryVs5Error_pIggzo_ACsAD_pIegnzo_TR + 18 16 WordPress 0x000000010c4c7844 $s9WordPress16EditorThemeQueryVs5Error_pIggzo_ACsAD_pIegnzo_TRTA + 20 17 libswiftCore.dylib 0x0000000112feb90d $sSTsE7forEachyyy7ElementQzKXEKF + 381 18 WordPress 0x000000010c4c757a $s9WordPress16EditorThemeStoreC14queriesChangedyyF + 186 19 WordPressFlux 0x0000000112e9f60f $s13WordPressFlux10QueryStoreC06activeD10References33_D0D38BB8DD876673D94E57E825FEF565LLSayAA0D3RefAELLVyq_GGvW + 1727 20 WordPressFlux 0x0000000112ea121f $s13WordPressFlux10QueryStoreC06activeD10References33_D0D38BB8DD876673D94E57E825FEF565LLSayAA0D3RefAELLVyq_GGvs + 319 21 WordPressFlux 0x0000000112ea22b6 $s13WordPressFlux10QueryStoreC5queryyAA7ReceiptCq_F + 598 22 WordPress 0x000000010c83a379 $s9WordPress23GutenbergViewControllerC16fetchEditorTheme33_DA3A37744181B0B94A9E4AD5BE8D30EFLLyyF + 201 23 WordPress 0x000000010c8396f7 $s9WordPress23GutenbergViewControllerC11viewDidLoadyyF + 327 24 WordPress 0x000000010c83a4cb $s9WordPress23GutenbergViewControllerC11viewDidLoadyyFTo + 43 25 UIKitCore 0x00007fff48c7598e -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 83 26 UIKitCore 0x00007fff48c7a8ac -[UIViewController loadViewIfRequired] + 1084 27 UIKitCore 0x00007fff48c7acc9 -[UIViewController view] + 27 28 UIKitCore 0x00007fff48beb8f5 -[UINavigationController preferredContentSize] + 187 29 UIKitCore 0x00007fff48b8f2c8 -[UIPresentationController preferredContentSizeDidChangeForChildContentContainer:] + 64 30 UIKitCore 0x00007fff48b8b10f __56-[UIPresentationController runTransitionForCurrentState]_block_invoke.465 + 178 31 UIKitCore 0x00007fff4932eb76 _runAfterCACommitDeferredBlocks + 352 32 UIKitCore 0x00007fff4931f304 _cleanUpAfterCAFlushAndRunDeferredBlocks + 248 33 UIKitCore 0x00007fff4934fb0d _afterCACommitHandler + 85 34 CoreFoundation 0x00007fff23da1087 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23 35 CoreFoundation 0x00007fff23d9bb3e __CFRunLoopDoObservers + 430 36 CoreFoundation 0x00007fff23d9c08a __CFRunLoopRun + 1226 37 CoreFoundation 0x00007fff23d9b8a4 CFRunLoopRunSpecific + 404 38 GraphicsServices 0x00007fff38c39bbe GSEventRunModal + 139 39 UIKitCore 0x00007fff49325968 UIApplicationMain + 1605 40 WordPress 0x000000010cdf9d24 main + 500 41 libdyld.dylib 0x00007fff520ce1fd start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException
@chipsnyder would you say this looks like it deserves a separate issue or this one should be reopened?
@guarani Thanks for the ping. I'd be happy to look into this a bit more.
would you say this looks like it deserves a separate issue or this one should be reopened?
That's a good question. Can you recreate the error with the steps above?
steps
If so then I think we can reopen this, if not I would suggest opening a new issue so we have the steps you're using.
Hi @chipsnyder, that's a good point!
I just tested now and I can't reproduce with the steps to reproduce from this issue, so I'll go ahead and create a new issue.
Good catch @Guarani !
Frame 9 shows:
9 WordPress 0x000000010bf6bd09 -[Blog wordPressOrgRestApi]
If you were testing on a WPCom site, it seems to be exactly the same error.
@chipsnyder - maybe we got a new retain cycle somewhere else?
Probably we should have this automatically tested somehow.
maybe we got a new retain cycle somewhere else?
Yeah, I was thinking the same thing @etoledom.
Probably we should have this automatically tested somehow.
Adding some tests would be nice. However, I'm not sure what that test would look like since the error is more a symptom of the problem. We could more gracefully handle not requesting in this case, but that wouldn't alert us to the retain cycle. I think the best way to test it would be around increasing our testing of the features we have.
Do you have any ideas on how we could test this?
I haven't gotten around to creating a separate issue yet, just want to note that I experienced this crash again today after logging out and logging in again via a magic link.
See logs
2020-08-05 12:09:49.314118-0400 WordPress[19877:3800456] Task <9D07175D-9EAE-42CF-8197-D497ED9F9140>.<22> HTTP load failed, 0/0 bytes (error code: -1004 [1:61])
2020-08-05 12:09:49.314526-0400 WordPress[19877:3800498] Task <9D07175D-9EAE-42CF-8197-D497ED9F9140>.<22> finished with error [-1004] Error Domain=NSURLErrorDomain Code=-1004 "Could not connect to the server." UserInfo={NSUnderlyingError=0x7fc1b0f09670 {Error Domain=kCFErrorDomainCFNetwork Code=-1004 "(null)" UserInfo={_kCFStreamErrorCodeKey=61, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=http://localhost:8081/status, NSErrorFailingURLKey=http://localhost:8081/status, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=61, NSLocalizedDescription=Could not connect to the server.}
CoreData: sql: SELECT 0, t0.Z_PK FROM ZBLOG t0
CoreData: annotation: sql connection fetch time: 0.0002s
CoreData: annotation: total fetch execution time: 0.0004s for 1 rows.
CoreData: sql: SELECT 0, t0.Z_PK FROM ZBLOG t0
CoreData: annotation: sql connection fetch time: 0.0002s
CoreData: annotation: total fetch execution time: 0.0005s for 1 rows.
2020-08-05 12:09:49.376453-0400 WordPress[19877:3764401] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSRegularExpression enumerateMatchesInString:options:range:usingBlock:]: nil argument'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23e3de6e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff512539b2 objc_exception_throw + 48
2 Foundation 0x00007fff25a45320 -[NSRegularExpression(NSMatching) matchesInString:options:range:] + 0
3 Foundation 0x00007fff25a453b2 -[NSRegularExpression(NSMatching) matchesInString:options:range:] + 146
4 Foundation 0x00007fff25a457fd -[NSRegularExpression(NSReplacement) stringByReplacingMatchesInString:options:range:withTemplate:] + 176
5 WordPress 0x00000001033aab89 -[Blog urlWithPath:] + 345
6 WordPress 0x000000010425f845 $s9WordPress7apiBase33_27EC9C948CC854094B4492A03135FD18LL4blog10Foundation3URLVSgSo4BlogC_tF + 373
7 WordPress 0x000000010425fb44 $s12WordPressKit0aB10OrgRestApiC0aB0E4blogACSgSo4BlogC_tcfc + 276
8 WordPress 0x000000010425ff73 $s12WordPressKit0aB10OrgRestApiC0aB0E4blogACSgSo4BlogC_tcfcTo + 51
9 WordPress 0x00000001033af439 -[Blog wordPressOrgRestApi] + 73
10 WordPress 0x0000000103950b59 $s9WordPress23GutenbergNetworkRequestV017performSelfHostedE033_C5237879BCC4451BCD9D90EA1DA24FAALL10completionyys6ResultOyypSo7NSErrorCGc_tF + 153
11 WordPress 0x000000010394fb08 $s9WordPress23GutenbergNetworkRequestV010selfHostedE033_C5237879BCC4451BCD9D90EA1DA24FAALL10completionyys6ResultOyypSo7NSErrorCGc_tF + 40
12 WordPress 0x000000010394f875 $s9WordPress23GutenbergNetworkRequestV7request10completionyys6ResultOyypSo7NSErrorCGc_tF + 341
13 WordPress 0x00000001038d5eae $s9WordPress16EditorThemeStoreC05fetchD033_97C339A53F625C50005B8CAC06D60566LL3forySo4BlogC_tF + 366
14 WordPress 0x00000001038d5d14 $s9WordPress16EditorThemeStoreC14queriesChangedyyFyAA0cD5QueryVXEfU_ + 68
15 WordPress 0x00000001038d5f02 $s9WordPress16EditorThemeQueryVs5Error_pIggzo_ACsAD_pIegnzo_TR + 18
16 WordPress 0x00000001038d5f54 $s9WordPress16EditorThemeQueryVs5Error_pIggzo_ACsAD_pIegnzo_TRTA + 20
17 libswiftCore.dylib 0x000000010a3b990d $sSTsE7forEachyyy7ElementQzKXEKF + 381
18 WordPress 0x00000001038d5c8a $s9WordPress16EditorThemeStoreC14queriesChangedyyF + 186
19 WordPressFlux 0x000000010a26d60f $s13WordPressFlux10QueryStoreC06activeD10References33_D0D38BB8DD876673D94E57E825FEF565LLSayAA0D3RefAELLVyq_GGvW + 1727
20 WordPressFlux 0x000000010a26f21f $s13WordPressFlux10QueryStoreC06activeD10References33_D0D38BB8DD876673D94E57E825FEF565LLSayAA0D3RefAELLVyq_GGvs + 319
21 WordPressFlux 0x000000010a2702b6 $s13WordPressFlux10QueryStoreC5queryyAA7ReceiptCq_F + 598
22 WordPress 0x0000000103c490b9 $s9WordPress23GutenbergViewControllerC16fetchEditorTheme33_DA3A37744181B0B94A9E4AD5BE8D30EFLLyyF + 201
23 WordPress 0x0000000103c48437 $s9WordPress23GutenbergViewControllerC11viewDidLoadyyF + 327
24 WordPress 0x0000000103c4920b $s9WordPress23GutenbergViewControllerC11viewDidLoadyyFTo + 43
25 UIKitCore 0x00007fff48c7598e -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 83
26 UIKitCore 0x00007fff48c7a8ac -[UIViewController loadViewIfRequired] + 1084
27 UIKitCore 0x00007fff48c7acc9 -[UIViewController view] + 27
28 UIKitCore 0x00007fff48beb8f5 -[UINavigationController preferredContentSize] + 187
29 UIKitCore 0x00007fff48b8f2c8 -[UIPresentationController preferredContentSizeDidChangeForChildContentContainer:] + 64
30 UIKitCore 0x00007fff48b8b10f __56-[UIPresentationController runTransitionForCurrentState]_block_invoke.465 + 178
31 UIKitCore 0x00007fff4932eb76 _runAfterCACommitDeferredBlocks + 352
32 UIKitCore 0x00007fff4931f304 _cleanUpAfterCAFlushAndRunDeferredBlocks + 248
33 UIKitCore 0x00007fff4934fb0d _afterCACommitHandler + 85
34 CoreFoundation 0x00007fff23da1087 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
35 CoreFoundation 0x00007fff23d9bb3e __CFRunLoopDoObservers + 430
36 CoreFoundation 0x00007fff23d9c08a __CFRunLoopRun + 1226
37 CoreFoundation 0x00007fff23d9b8a4 CFRunLoopRunSpecific + 404
38 GraphicsServices 0x00007fff38c39bbe GSEventRunModal + 139
39 UIKitCore 0x00007fff49325968 UIApplicationMain + 1605
40 WordPress 0x00000001042082a4 main + 500
41 libdyld.dylib 0x00007fff520ce1fd start + 1
42 ??? 0x0000000000000005 0x0 + 5
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I'm not sure what that test would look like since the error is more a symptom of the problem.
Maybe a UI Test would be good, following the same steps to reproduce the crash.
Basically: Open Gutenberg on Simple Site - Log out - Log in - Open Gutenberg again on the same site.
We could try Unit Test cleaning the database in between creating Gutenberg instances but a Unit Test on GutenbergViewController seems tricky right now. (Something we can/should improve).
Let's be sure first if it's actually the same problem.
Anyway I'd ask @rachelmcr before implementing a UI Test for this scenario, since this is not a core flow for users.
My inclination would be to only implement a UI test if it's a critical/common flow for our users or if this is a recurring, high-impact issue and this is the best way to test for regressions.
Logging out and in again doesn't seem like a critical flow to me. I checked Sentry to get a sense of the impact and it looks like in the past 90 days it has happened ~200 times to 100 users (not high impact): https://sentry.io/share/issue/3cc1bd273a444d539a517e87a7f2fc27/
I'm concerned if we aren't sure how reliable the repro steps are and this is more of a side effect — possibly an inconsistent one — of the underlying problem. That said, if it isn't possible to unit test this and there's a reliable scenario where the issue appears, we can test it with a UI test. We should just be sure the benefit we're getting with the test is worth it.
FWIW I experienced a very similar crash today on WPiOS 15.8 after logging out and logging back in again. I could only reproduce it twice out of ten or so attempts — notably, the second time it happened was after a delay of five minutes between tries. (Update: Happened three times, still don't have concrete steps to reproduce.)
I checked Sentry to get a sense of the impact and it looks like in the past 90 days it has happened ~200 times to 100 users (not high impact): https://sentry.io/share/issue/3cc1bd273a444d539a517e87a7f2fc27/
It looks like that issue is no longer active for the latest release. Searching Sentry for enumerateMatchesInString in the appStore environment under WPiOS v15.8 results in two issues (both are for 15.8.0.2.):
Not a high number of crashes, but noting here in case it's useful later.