|
10 | 10 | import static com.facebook.infer.annotation.Assertions.assertNotNull; |
11 | 11 | import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE; |
12 | 12 |
|
| 13 | +import android.text.Editable; |
| 14 | +import android.text.SpannableStringBuilder; |
| 15 | + |
13 | 16 | import androidx.annotation.Nullable; |
14 | 17 | import com.facebook.debug.holder.PrinterHolder; |
15 | 18 | import com.facebook.debug.tags.ReactDebugOverlayTags; |
@@ -356,37 +359,44 @@ public void invoke(JSInstance jsInstance, ReadableArray parameters) { |
356 | 359 | mArgumentExtractors[i].extractArgument(jsInstance, parameters, jsArgumentsConsumed); |
357 | 360 | jsArgumentsConsumed += mArgumentExtractors[i].getJSArgumentsNeeded(); |
358 | 361 | } |
359 | | - } catch (UnexpectedNativeTypeException e) { |
| 362 | + } catch (UnexpectedNativeTypeException | NullPointerException e) { |
360 | 363 | throw new NativeArgumentsParseException( |
361 | 364 | e.getMessage() |
362 | 365 | + " (constructing arguments for " |
363 | 366 | + traceName |
364 | 367 | + " at argument index " |
365 | 368 | + getAffectedRange( |
366 | 369 | jsArgumentsConsumed, mArgumentExtractors[i].getJSArgumentsNeeded()) |
367 | | - + ")", |
| 370 | + + ") with parameters " |
| 371 | + + parameters.toArrayList(), |
368 | 372 | e); |
369 | 373 | } |
370 | 374 |
|
371 | 375 | try { |
372 | 376 | mMethod.invoke(mModuleWrapper.getModule(), mArguments); |
373 | | - } catch (IllegalArgumentException ie) { |
374 | | - throw new RuntimeException("Could not invoke " + traceName, ie); |
375 | | - } catch (IllegalAccessException iae) { |
376 | | - throw new RuntimeException("Could not invoke " + traceName, iae); |
| 377 | + } catch (IllegalArgumentException | IllegalAccessException e) { |
| 378 | + throw new RuntimeException(createInvokeExceptionMessage(traceName, parameters), e); |
377 | 379 | } catch (InvocationTargetException ite) { |
378 | 380 | // Exceptions thrown from native module calls end up wrapped in InvocationTargetException |
379 | 381 | // which just make traces harder to read and bump out useful information |
380 | 382 | if (ite.getCause() instanceof RuntimeException) { |
381 | 383 | throw (RuntimeException) ite.getCause(); |
382 | 384 | } |
383 | | - throw new RuntimeException("Could not invoke " + traceName, ite); |
| 385 | + throw new RuntimeException(createInvokeExceptionMessage(traceName, parameters), ite); |
384 | 386 | } |
385 | 387 | } finally { |
386 | 388 | SystraceMessage.endSection(TRACE_TAG_REACT_JAVA_BRIDGE).flush(); |
387 | 389 | } |
388 | 390 | } |
389 | 391 |
|
| 392 | + /** |
| 393 | + * Makes it easier to determine the cause of an error invoking a native method from Javascript |
| 394 | + * code by adding the function and parameters. |
| 395 | + */ |
| 396 | + private static String createInvokeExceptionMessage(String traceName, ReadableArray parameters) { |
| 397 | + return "Could not invoke " + traceName + " with parameters " + parameters.toArrayList(); |
| 398 | + } |
| 399 | + |
390 | 400 | /** |
391 | 401 | * Determines how the method is exported in JavaScript: METHOD_TYPE_ASYNC for regular methods |
392 | 402 | * METHOD_TYPE_PROMISE for methods that return a promise object to the caller. METHOD_TYPE_SYNC |
|
0 commit comments