From da84eba318ae69fea28f40418178bdeb35c4a99b Mon Sep 17 00:00:00 2001 From: Jamie Curtis Date: Tue, 27 Feb 2018 04:16:01 -0800 Subject: [PATCH] Catch exception and report it when making a network request with invalid URL on Android Summary: 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. Fix using fetch on Android with user generated input. Added relevant unit test `./scripts/run-android-local-unit-tests.sh` all pass [ANDROID] [BUGFIX] [fetch] - Allow "unexpected url" exception to be caught on Android when using fetch Closes https://github.com/facebook/react-native/pull/18103 Differential Revision: D7097110 Pulled By: hramos fbshipit-source-id: 69144e8a0f7404d9bcc7c71a94650de36a48c84a --- .../modules/network/NetworkingModule.java | 8 +++++- .../modules/network/NetworkingModuleTest.java | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) 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 263515711..cc9c63490 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 @@ -264,7 +264,13 @@ public final class NetworkingModule extends ReactContextBaseJavaModule { 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 29e3e6a27..456a108f3 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 @@ -168,6 +168,34 @@ public class NetworkingModuleTest { 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());