Handle network error during proxy config better.

Don't assume we need a proxy and show the user an inscrutable dialog. Pop up a
dialog that says that we were unable to connect and tell them to check their
internet connection. From there they can either try again or configure a proxy
if they know that's a thing they might need to do.
This commit is contained in:
Michael Bayne
2026-05-12 12:47:19 -07:00
parent a5eae1a80c
commit f621e7d810
3 changed files with 61 additions and 26 deletions
@@ -38,6 +38,7 @@ import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import com.samskivert.swing.util.SwingUtil;
import com.threerings.getdown.data.Application;
@@ -202,11 +203,17 @@ public abstract class Getdown
_dead = false;
// if we fail to detect a proxy, but we're allowed to run offline, then go ahead and
// run the app anyway because we're prepared to cope with not being able to update
if (detectProxy() || _app.allowOffline()) getdown();
else requestProxyInfo(false);
try {
if (detectProxy() || _app.allowOffline()) getdown();
else requestProxyInfo(false);
} catch (IOException ioe) {
log.info("Failed to detect if proxy is needed", "error", ioe);
log.info("We may need a proxy, or maybe their network is down.");
showConnectionFailedDialog();
}
}
protected boolean detectProxy () {
protected boolean detectProxy () throws IOException {
// first we have to initialize our application to get the appbase URL, etc.
log.info("Checking whether we need to use a proxy...");
try {
@@ -223,6 +230,7 @@ public abstract class Getdown
// see if we actually need a proxy
updateStatus("m.detecting_proxy");
URL configURL = _app.getConfigResource().getRemote();
// if this detection fails to connect, we'll let the IOException propagate out
if (!ProxyUtil.canLoadWithoutProxy(configURL, tryNoProxy ? 2 : 5)) {
// if we didn't auto-detect proxy first thing, do auto-detect now
return tryNoProxy ? ProxyUtil.autoDetectProxy(_app) : false;
@@ -262,6 +270,33 @@ public abstract class Getdown
showContainer();
}
/**
* Shows a dialog informing the user that we could not connect to the download servers,
* with buttons to try again or configure a proxy.
*/
protected void showConnectionFailedDialog () {
if (_silent) {
log.warning("Unable to connect to download servers. Exiting.");
return;
}
String message = _msgs.getString("m.proxy_connect_failed");
String tryAgain = _msgs.getString("m.try_again");
String configureProxy = _msgs.getString("m.configure_proxy_button");
Object[] options = { tryAgain, configureProxy };
int choice = JOptionPane.showOptionDialog(
null, message, "",
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
null, options, options[0]);
if (choice == JOptionPane.YES_OPTION) {
// "Try again" — re-run the update/launch sequence
run();
} else if (choice == JOptionPane.NO_OPTION) {
// "Configure proxy" — show the proxy configuration panel
requestProxyInfo(false);
}
}
/**
* Downloads and installs (without verifying) any resources that are marked with a
* {@code PRELOAD} attribute.
@@ -124,35 +124,31 @@ public final class ProxyUtil {
}
public static boolean canLoadWithoutProxy (URL rurl, int timeoutSeconds)
throws IOException
{
log.info("Attempting to fetch without proxy: " + rurl);
URLConnection conn = Connector.DEFAULT.open(rurl, timeoutSeconds, timeoutSeconds);
// if the appbase is not an HTTP/S URL (like file:), then we don't need a proxy
if (!(conn instanceof HttpURLConnection)) {
return true;
}
// otherwise, try to make a HEAD request for this URL
HttpURLConnection hcon = (HttpURLConnection)conn;
try {
URLConnection conn = Connector.DEFAULT.open(rurl, timeoutSeconds, timeoutSeconds);
// if the appbase is not an HTTP/S URL (like file:), then we don't need a proxy
if (!(conn instanceof HttpURLConnection)) {
hcon.setRequestMethod("HEAD");
hcon.connect();
// make sure we got a satisfactory response code
int rcode = hcon.getResponseCode();
if (rcode == HttpURLConnection.HTTP_PROXY_AUTH ||
rcode == HttpURLConnection.HTTP_FORBIDDEN) {
log.warning("Got an 'HTTP credentials needed' response", "code", rcode);
return false;
} else {
return true;
}
// otherwise, try to make a HEAD request for this URL
HttpURLConnection hcon = (HttpURLConnection)conn;
try {
hcon.setRequestMethod("HEAD");
hcon.connect();
// make sure we got a satisfactory response code
int rcode = hcon.getResponseCode();
if (rcode == HttpURLConnection.HTTP_PROXY_AUTH ||
rcode == HttpURLConnection.HTTP_FORBIDDEN) {
log.warning("Got an 'HTTP credentials needed' response", "code", rcode);
} else {
return true;
}
} finally {
hcon.disconnect();
}
} catch (IOException ioe) {
log.info("Failed to HEAD " + rurl + ": " + ioe);
log.info("We probably need a proxy, but auto-detection failed.");
} finally {
hcon.disconnect();
}
return false;
}
public static void configProxy (Application app, String host, String port,
@@ -11,6 +11,10 @@ m.abort_cancel = Continue installation
m.detecting_proxy = Trying to auto-detect proxy settings
m.proxy_connect_failed = We were unable to connect to the download servers. Please check your Internet connection.
m.try_again = Try again
m.configure_proxy_button = Configure proxy
m.configure_proxy = <html>We were unable to connect to the application server to download data. \
<p> Please make sure that no virus scanner or firewall is blocking network communication with \
the server. \