1919import java .lang .reflect .Field ;
2020import java .lang .reflect .InvocationTargetException ;
2121import java .lang .reflect .Modifier ;
22+ import java .util .ArrayList ;
23+ import java .util .List ;
2224import java .util .concurrent .TimeUnit ;
2325import java .util .concurrent .atomic .AtomicReference ;
2426
@@ -31,12 +33,6 @@ public class UncaughtExceptionHandlerTest {
3133 private Context context ;
3234 private BacktraceCredentials credentials ;
3335
34- @ Before
35- public void setUp () {
36- context = InstrumentationRegistry .getInstrumentation ().getContext ();
37- credentials = new BacktraceCredentials ("https://example-endpoint.com/" , "" );
38- }
39-
4036 private static void setRootHandler (Thread .UncaughtExceptionHandler customRootHandler , Thread .UncaughtExceptionHandler newRootHandler ) {
4137 try {
4238 Field field = BacktraceExceptionHandler .class .getDeclaredField ("rootHandler" );
@@ -47,7 +43,6 @@ private static void setRootHandler(Thread.UncaughtExceptionHandler customRootHan
4743 }
4844 }
4945
50-
5146 private static BacktraceExceptionHandler createBacktraceExceptionHandler (BacktraceClient client ) throws NoSuchMethodException , InvocationTargetException , IllegalAccessException , InstantiationException {
5247 Constructor <BacktraceExceptionHandler > constructor = BacktraceExceptionHandler .class .getDeclaredConstructor (BacktraceClient .class );
5348 assertTrue (Modifier .isPrivate (constructor .getModifiers ()));
@@ -57,6 +52,12 @@ private static BacktraceExceptionHandler createBacktraceExceptionHandler(Backtra
5752 return exceptionHandler ;
5853 }
5954
55+ @ Before
56+ public void setUp () {
57+ context = InstrumentationRegistry .getInstrumentation ().getContext ();
58+ credentials = new BacktraceCredentials ("https://example-endpoint.com/" , "" );
59+ }
60+
6061 @ Test ()
6162 public void testUncaughtException () throws InvocationTargetException , NoSuchMethodException , IllegalAccessException , InstantiationException {
6263 // GIVEN
@@ -131,4 +132,93 @@ public void testUncaughtError() throws InvocationTargetException, NoSuchMethodEx
131132 assertEquals ("Unhandled Exception" , testedReportData .getReport ().attributes .get ("error.type" ));
132133 assertTrue (testedReportData .getReport ().exceptionTypeReport );
133134 }
135+
136+ @ Test ()
137+ public void testUncaughtInnerExceptionsGeneration () throws InvocationTargetException , NoSuchMethodException , IllegalAccessException , InstantiationException {
138+ // GIVEN
139+ final int expectedNumberOfExceptions = 2 ;
140+ final Waiter waiter = new Waiter ();
141+ final String innerExceptionMessage = "Cause exception message" ;
142+ final Exception cause = new IllegalArgumentException (innerExceptionMessage );
143+ final String outerExceptionMessage = "Outer exception" ;
144+ final Exception exception = new IllegalArgumentException (outerExceptionMessage , cause );
145+ final BacktraceClient client = new BacktraceClient (context , credentials );
146+ client .sendInnerExceptions (true );
147+ client .sendSuppressedExceptions (true );
148+
149+ final List <BacktraceData > unhandledExceptionData = new ArrayList <>();
150+ client .setOnRequestHandler (data -> {
151+ unhandledExceptionData .add (data );
152+ if (unhandledExceptionData .size () == expectedNumberOfExceptions ) {
153+ waiter .resume ();
154+ }
155+ return new BacktraceResult (data .getReport (), data .getReport ().message ,
156+ BacktraceResultStatus .Ok );
157+ });
158+
159+ final BacktraceExceptionHandler handler = createBacktraceExceptionHandler (client );
160+
161+ // WHEN
162+ handler .uncaughtException (Thread .currentThread (), exception );
163+
164+ // WAIT FOR THE RESULT FROM ANOTHER THREAD
165+ try {
166+ waiter .await (5 , TimeUnit .SECONDS );
167+ } catch (Exception ex ) {
168+ fail (ex .getMessage ());
169+ }
170+
171+ // THEN
172+ assertEquals (expectedNumberOfExceptions , unhandledExceptionData .size ());
173+
174+ final BacktraceData outerException = unhandledExceptionData .get (0 );
175+ final BacktraceData innerException = unhandledExceptionData .get (unhandledExceptionData .size () - 1 );
176+ assertEquals (outerExceptionMessage , outerException .attributes .get ("error.message" ));
177+ assertEquals (innerExceptionMessage , innerException .attributes .get ("error.message" ));
178+ }
179+
180+ @ Test ()
181+ public void testUncaughtInnerExceptionsErrorAttributes () throws InvocationTargetException , NoSuchMethodException , IllegalAccessException , InstantiationException {
182+ // GIVEN
183+ final int expectedNumberOfExceptions = 2 ;
184+ final Waiter waiter = new Waiter ();
185+ final String innerExceptionMessage = "Cause exception message" ;
186+ final Exception cause = new IllegalArgumentException (innerExceptionMessage );
187+ final String outerExceptionMessage = "Outer exception" ;
188+ final Exception exception = new IllegalArgumentException (outerExceptionMessage , cause );
189+ final BacktraceClient client = new BacktraceClient (context , credentials );
190+ client .sendInnerExceptions (true );
191+ client .sendSuppressedExceptions (true );
192+
193+ final List <BacktraceData > unhandledExceptionData = new ArrayList <>();
194+ client .setOnRequestHandler (data -> {
195+ unhandledExceptionData .add (data );
196+ if (unhandledExceptionData .size () == expectedNumberOfExceptions ) {
197+ waiter .resume ();
198+ }
199+ return new BacktraceResult (data .getReport (), data .getReport ().message ,
200+ BacktraceResultStatus .Ok );
201+ });
202+
203+ final BacktraceExceptionHandler handler = createBacktraceExceptionHandler (client );
204+
205+ // WHEN
206+ handler .uncaughtException (Thread .currentThread (), exception );
207+
208+ // WAIT FOR THE RESULT FROM ANOTHER THREAD
209+ try {
210+ waiter .await (5 , TimeUnit .SECONDS );
211+ } catch (Exception ex ) {
212+ fail (ex .getMessage ());
213+ }
214+
215+ // THEN
216+ final BacktraceData outerException = unhandledExceptionData .get (0 );
217+ final BacktraceData innerException = unhandledExceptionData .get (unhandledExceptionData .size () - 1 );
218+ assertEquals (outerException .attributes .get ("error.trace" ), innerException .attributes .get ("error.trace" ));
219+ assertEquals (outerException .uuid , innerException .attributes .get ("error.parent" ));
220+ assertNull (outerException .attributes .get ("error.parent" ));
221+ assertEquals (BacktraceAttributeConsts .UnhandledExceptionAttributeType , outerException .attributes .get ("error.type" ));
222+ assertEquals (BacktraceAttributeConsts .UnhandledExceptionAttributeType , innerException .attributes .get ("error.type" ));
223+ }
134224}
0 commit comments