{"action":"opened","issue":{"url":"https://api.github.com/repos/square/okhttp/issues/4198","repository_url":"https://api.github.com/repos/square/okhttp","labels_url":"https://api.github.com/repos/square/okhttp/issues/4198/labels{/name}","comments_url":"https://api.github.com/repos/square/okhttp/issues/4198/comments","events_url":"https://api.github.com/repos/square/okhttp/issues/4198/events","html_url":"https://github.com/square/okhttp/issues/4198","id":348829187,"node_id":"MDU6SXNzdWUzNDg4MjkxODc=","number":4198,"title":"[BUG] RuntimeException thrown in Interceptor doesn't call onFailure","user":{"login":"arcao","id":315097,"node_id":"MDQ6VXNlcjMxNTA5Nw==","avatar_url":"https://avatars3.githubusercontent.com/u/315097?v=4","gravatar_id":"","url":"https://api.github.com/users/arcao","html_url":"https://github.com/arcao","followers_url":"https://api.github.com/users/arcao/followers","following_url":"https://api.github.com/users/arcao/following{/other_user}","gists_url":"https://api.github.com/users/arcao/gists{/gist_id}","starred_url":"https://api.github.com/users/arcao/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arcao/subscriptions","organizations_url":"https://api.github.com/users/arcao/orgs","repos_url":"https://api.github.com/users/arcao/repos","events_url":"https://api.github.com/users/arcao/events{/privacy}","received_events_url":"https://api.github.com/users/arcao/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-08-08T17:53:21Z","updated_at":"2018-08-08T17:53:21Z","closed_at":null,"author_association":"NONE","body":"What kind of issue is this?\r\n - [x] Bug report. If you’ve found a bug, spend the time to write a failing test. Bugs with tests\r\n       get fixed. Here’s an example: https://gist.github.com/swankjesse/981fcae102f513eb13ed\r\n\r\nWhen RuntimeException is accidentally thrown inside `Interceptor.intercept(...)` method, the exception is not handled in `okhttp3.RealCall$AsyncCall.execute()` method. I think, the runtime exception should be encapsulated to `IOException` and `Callback.onFailure(...)` should be called.\r\n\r\nSample code in kotlin:\r\n```kotlin\r\nimport okhttp3.*\r\nimport org.junit.jupiter.api.Assertions.assertNotNull\r\nimport org.junit.jupiter.api.Assertions.fail\r\nimport org.junit.jupiter.api.Test\r\nimport java.io.IOException\r\nimport java.util.concurrent.CountDownLatch\r\nimport java.util.concurrent.TimeUnit\r\nimport java.util.concurrent.atomic.AtomicReference\r\n\r\nobject OkHttpInterceptorBugTest {\r\n    @Test\r\n    fun listenerOnFailureShouldReturnRuntimeException() {\r\n        val okHttp = OkHttpClient.Builder()\r\n                .addInterceptor {\r\n                    throw RuntimeException(\"test\")\r\n                }\r\n                .build()\r\n\r\n        val call = okHttp.newCall(Request.Builder().url(\"http://example.com/\").build())\r\n\r\n        val latch = CountDownLatch(1)\r\n        val reference = AtomicReference<Throwable>()\r\n        call.enqueue(object: Callback {\r\n            override fun onFailure(call: Call?, e: IOException?) {\r\n                reference.set(e)\r\n                latch.countDown()\r\n            }\r\n\r\n            override fun onResponse(call: Call?, response: Response?) {\r\n                latch.countDown()\r\n            }\r\n        })\r\n\r\n        val timeout = !latch.await(5, TimeUnit.SECONDS)\r\n\r\n        call.cancel()\r\n        if (timeout) fail<Unit>(\"Timeout occurs\")\r\n\r\n        assertNotNull(reference.get(), \"Throwable expected.\")\r\n    }\r\n}\r\n```\r\n\r\nStack trace:\r\n```\r\nException in thread \"OkHttp Dispatcher\" java.lang.RuntimeException: test\r\n\tat OkHttpInterceptorBugTest$listenerOnFailureShouldReturnRuntimeException$okHttp$1.intercept(OkHttpInterceptorBugTest.kt:33)\r\n\tat OkHttpInterceptorBugTest$listenerOnFailureShouldReturnRuntimeException$okHttp$1.intercept(OkHttpInterceptorBugTest.kt:11)\r\n\tat okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)\r\n\tat okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)\r\n\tat okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)\r\n\tat okhttp3.RealCall$AsyncCall.execute(RealCall.java:147)\r\n\tat okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)\r\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\r\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\r\n\tat java.lang.Thread.run(Thread.java:748)\r\n\r\norg.opentest4j.AssertionFailedError: Timeout occurs\r\n\r\n\tat org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:38)\r\n\tat org.junit.jupiter.api.Assertions.fail(Assertions.java:74)\r\n\tat OkHttpInterceptorBugTest.listenerOnFailureShouldReturnRuntimeException(OkHttpInterceptorBugTest.kt:55)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.lang.reflect.Method.invoke(Method.java:498)\r\n\tat org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:515)\r\n\tat org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)\r\n\tat org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)\r\n\tat org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)\r\n\tat org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)\r\n\tat org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)\r\n\tat org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)\r\n\tat org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:134)\r\n\tat org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)\r\n\tat org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:128)\r\n\tat org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:109)\r\n\tat java.util.ArrayList.forEach(ArrayList.java:1257)\r\n\tat org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)\r\n\tat org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:138)\r\n\tat org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)\r\n\tat org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:128)\r\n\tat org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:109)\r\n\tat java.util.ArrayList.forEach(ArrayList.java:1257)\r\n\tat org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)\r\n\tat org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:138)\r\n\tat org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)\r\n\tat org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:128)\r\n\tat org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:109)\r\n\tat org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)\r\n\tat org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:49)\r\n\tat org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:47)\r\n\tat org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:184)\r\n\tat org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:152)\r\n\tat org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:166)\r\n\tat org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:145)\r\n\tat org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:92)\r\n\tat com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)\r\n\tat com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)\r\n\tat com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)\r\n\tat com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)\r\n```"}}
{"actor":{"display_login":"arcao"}}