From d475baeebecc7069541117671cd7a6003b5e8fe9 Mon Sep 17 00:00:00 2001 From: Jamie Curtis Date: Mon, 26 Feb 2018 15:02:52 -0400 Subject: [PATCH] Catch exception and report it when making a network request with invalid URL on Android Currently if you invoke `fetch()` with an invalid URL ("aaa" for example) you cannot catch the error in javascript since it's not reported. Instead the entire app crashes. Fixes #7436 and #18087 Hopefully. --- .../modules/network/NetworkingModule.java | 8 ++++- .../modules/network/NetworkingModuleTest.java | 30 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java index 3f483798c81162..5211c70f5a280a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java @@ -266,7 +266,13 @@ public void sendRequest( return; } - Request.Builder requestBuilder = new Request.Builder().url(url); + Request.Builder requestBuilder; + try { + requestBuilder = new Request.Builder().url(url); + } catch (Exception e) { + ResponseUtil.onRequestError(eventEmitter, requestId, e.getMessage(), null); + return; + } if (requestId != 0) { requestBuilder.tag(requestId); diff --git a/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java b/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java index a42231b55fd5be..d2dfbba5c95314 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java @@ -170,6 +170,34 @@ public void testFailPostWithoutContentType() throws Exception { verifyErrorEmit(emitter, 0); } + @Test + public void testFailInvalidUrl() throws Exception { + RCTDeviceEventEmitter emitter = mock(RCTDeviceEventEmitter.class); + ReactApplicationContext context = mock(ReactApplicationContext.class); + when(context.getJSModule(any(Class.class))).thenReturn(emitter); + + OkHttpClient httpClient = mock(OkHttpClient.class); + OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); + when(clientBuilder.build()).thenReturn(httpClient); + when(httpClient.newBuilder()).thenReturn(clientBuilder); + NetworkingModule networkingModule = new NetworkingModule(context, "", httpClient); + + mockEvents(); + + networkingModule.sendRequest( + "GET", + "aaa", + /* requestId */ 0, + /* headers */ JavaOnlyArray.of(), + /* body */ null, + /* responseType */ "text", + /* useIncrementalUpdates*/ true, + /* timeout */ 0, + /* withCredentials */ false); + + verifyErrorEmit(emitter, 0); + } + private static void verifyErrorEmit(RCTDeviceEventEmitter emitter, int requestId) { ArgumentCaptor captor = ArgumentCaptor.forClass(WritableArray.class); verify(emitter).emit(eq("didCompleteNetworkResponse"), captor.capture()); @@ -630,4 +658,4 @@ public Object answer(InvocationOnMock invocation) throws Throwable { assertThat(requestIdArguments.getAllValues().contains(idx + 1)).isTrue(); } } -} \ No newline at end of file +}