Repository: tootallnate/java-websocket
Issue: IOException wrapped in InternalError not handled properly

**Describe the bug**
The call to `socket.connect(...)` at `WebSocketClient:436` can throw a `java.lang.InternalError` that is currently not handled in the enclosing try/catch as it extends `java.lang.Error` and not `java.lang.Exception`

This `InternalError` wraps a `java.lang.IOException` that contains useful information to the websocket engine to hande this case.

**To Reproduce**
Steps to reproduce the behavior:
1. Install a proxy, i.e. squid
2. Make it deny connections

**Example application to reproduce the issue**
Use the previously installed proxy in the `ProxyClientExample`

**Expected behavior**
An IOException handled by the underlying websocket engine

**Debug log**
```
Exception in thread "WebSocketConnectReadThread-11" java.lang.InternalError: Should not reach here
	at java.net.HttpConnectSocketImpl.doTunneling(HttpConnectSocketImpl.java:181)
	at java.net.HttpConnectSocketImpl.doTunnel(HttpConnectSocketImpl.java:168)
	at java.net.HttpConnectSocketImpl.access$200(HttpConnectSocketImpl.java:44)
	at java.net.HttpConnectSocketImpl$2.run(HttpConnectSocketImpl.java:151)
	at java.net.HttpConnectSocketImpl$2.run(HttpConnectSocketImpl.java:149)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.HttpConnectSocketImpl.privilegedDoTunnel(HttpConnectSocketImpl.java:148)
	at java.net.HttpConnectSocketImpl.connect(HttpConnectSocketImpl.java:111)
	at java.net.Socket.connect(Socket.java:589)
	at org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:436)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.net.HttpConnectSocketImpl.doTunneling(HttpConnectSocketImpl.java:179)
	... 10 more
Caused by: java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 403 Forbidden"
	at sun.net.www.protocol.http.HttpURLConnection.doTunneling(HttpURLConnection.java:2142)
	... 15 more
```

**Environment(please complete the following information):**
 - Version used: 1.4.0
 - Java version: 1.8.0_181
 - Operating System and version: Ubuntu 16.04 LTS
 - Endpoint Name and version: "ws://echo.websocket.org"
 - Link to your project: ProxyClientExample in the examples folder

**Additional context**
This is my first time reporting an issue on a open source project.
I'm open to feedback :)


Changed files:
src/main/java/org/java_websocket/client/WebSocketClient.java

diff --git a/src/main/java/org/java_websocket/client/WebSocketClient.java b/src/main/java/org/java_websocket/client/WebSocketClient.java
index f5cd9b1..7a93a0a 100644
--- a/src/main/java/org/java_websocket/client/WebSocketClient.java
+++ b/src/main/java/org/java_websocket/client/WebSocketClient.java
@@ -28,6 +28,7 @@ package org.java_websocket.client;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
@@ -480,6 +481,15 @@ public abstract class WebSocketClient extends AbstractWebSocket implements Runna
 			onWebsocketError( engine, e );
 			engine.closeConnection( CloseFrame.NEVER_CONNECTED, e.getMessage() );
 			return;
+		} catch (InternalError e) {
+			// https://bugs.openjdk.java.net/browse/JDK-8173620
+			if (e.getCause() instanceof InvocationTargetException && e.getCause().getCause() instanceof IOException) {
+				IOException cause = (IOException) e.getCause().getCause();
+				onWebsocketError(engine, cause);
+				engine.closeConnection(CloseFrame.NEVER_CONNECTED, cause.getMessage());
+				return;
+			}
+			throw e;
 		}
 
 		writeThread = new Thread( new WebsocketWriteThread(this) );