@@ -776,6 +776,80 @@ - (void)testIgnoreErrorsRegexAndStringBothWork
776776 XCTAssertNotNil (result3, @" Event with non-matching error should not be dropped" );
777777}
778778
779+ - (void )testBeforeSendFiltersOutUnhandledJSException
780+ {
781+ RNSentry *rnSentry = [[RNSentry alloc ] init ];
782+ NSError *error = nil ;
783+ NSMutableDictionary *mockedOptions = [@{
784+ @" dsn" : @" https://abc@def.ingest.sentry.io/1234567" ,
785+ } mutableCopy];
786+ mockedOptions = [rnSentry prepareOptions: mockedOptions];
787+ SentryOptions *options = [SentrySDKWrapper createOptionsWithDictionary: mockedOptions
788+ isSessionReplayEnabled: NO
789+ error: &error];
790+ XCTAssertNotNil (options);
791+ XCTAssertNil (error);
792+
793+ SentryEvent *event = [[SentryEvent alloc ] init ];
794+ SentryException *exception = [SentryException alloc ];
795+ exception.type = @" Unhandled JS Exception" ;
796+ exception.value = @" Error: Test error" ;
797+ event.exceptions = @[ exception ];
798+ SentryEvent *result = options.beforeSend (event);
799+ XCTAssertNil (result, @" Event with Unhandled JS Exception should be dropped" );
800+ }
801+
802+ - (void )testBeforeSendFiltersOutJSErrorCppException
803+ {
804+ RNSentry *rnSentry = [[RNSentry alloc ] init ];
805+ NSError *error = nil ;
806+ NSMutableDictionary *mockedOptions = [@{
807+ @" dsn" : @" https://abc@def.ingest.sentry.io/1234567" ,
808+ } mutableCopy];
809+ mockedOptions = [rnSentry prepareOptions: mockedOptions];
810+ SentryOptions *options = [SentrySDKWrapper createOptionsWithDictionary: mockedOptions
811+ isSessionReplayEnabled: NO
812+ error: &error];
813+ XCTAssertNotNil (options);
814+ XCTAssertNil (error);
815+
816+ // Test C++ exception with ExceptionsManager.reportException in value (actual format from New
817+ // Architecture) The exception type is "C++ Exception" and the value contains the mangled name
818+ // and error message
819+ SentryEvent *event1 = [[SentryEvent alloc ] init ];
820+ SentryException *exception1 = [SentryException alloc ];
821+ exception1.type = @" C++ Exception" ;
822+ exception1.value = @" N8facebook3jsi7JSErrorE: ExceptionsManager.reportException raised an "
823+ @" exception: Unhandled JS Exception: Error: Test error" ;
824+ event1.exceptions = @[ exception1 ];
825+ SentryEvent *result1 = options.beforeSend (event1);
826+ XCTAssertNil (
827+ result1, @" Event with ExceptionsManager.reportException in value should be dropped" );
828+
829+ // Test exception value containing ExceptionsManager.reportException (alternative format)
830+ SentryEvent *event2 = [[SentryEvent alloc ] init ];
831+ SentryException *exception2 = [SentryException alloc ];
832+ exception2.type = @" SomeOtherException" ;
833+ exception2.value = @" ExceptionsManager.reportException raised an exception: Unhandled JS "
834+ @" Exception: Error: Test" ;
835+ event2.exceptions = @[ exception2 ];
836+ SentryEvent *result2 = options.beforeSend (event2);
837+ XCTAssertNil (
838+ result2, @" Event with ExceptionsManager.reportException in value should be dropped" );
839+
840+ // Test that legitimate C++ exceptions without ExceptionsManager.reportException are not
841+ // filtered
842+ SentryEvent *event3 = [[SentryEvent alloc ] init ];
843+ SentryException *exception3 = [SentryException alloc ];
844+ exception3.type = @" C++ Exception" ;
845+ exception3.value = @" std::runtime_error: Some other C++ error occurred" ;
846+ event3.exceptions = @[ exception3 ];
847+ SentryEvent *result3 = options.beforeSend (event3);
848+ XCTAssertNotNil (result3,
849+ @" Legitimate C++ exception without ExceptionsManager.reportException should not be "
850+ @" dropped" );
851+ }
852+
779853- (void )testCreateOptionsWithDictionaryEnableSessionReplayInUnreliableEnvironmentDefault
780854{
781855 NSError *error = nil ;
0 commit comments