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.JButton;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JLayeredPane; import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import com.samskivert.swing.util.SwingUtil; import com.samskivert.swing.util.SwingUtil;
import com.threerings.getdown.data.Application; import com.threerings.getdown.data.Application;
@@ -202,11 +203,17 @@ public abstract class Getdown
_dead = false; _dead = false;
// if we fail to detect a proxy, but we're allowed to run offline, then go ahead and // 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 // run the app anyway because we're prepared to cope with not being able to update
try {
if (detectProxy() || _app.allowOffline()) getdown(); if (detectProxy() || _app.allowOffline()) getdown();
else requestProxyInfo(false); 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. // first we have to initialize our application to get the appbase URL, etc.
log.info("Checking whether we need to use a proxy..."); log.info("Checking whether we need to use a proxy...");
try { try {
@@ -223,6 +230,7 @@ public abstract class Getdown
// see if we actually need a proxy // see if we actually need a proxy
updateStatus("m.detecting_proxy"); updateStatus("m.detecting_proxy");
URL configURL = _app.getConfigResource().getRemote(); 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 (!ProxyUtil.canLoadWithoutProxy(configURL, tryNoProxy ? 2 : 5)) {
// if we didn't auto-detect proxy first thing, do auto-detect now // if we didn't auto-detect proxy first thing, do auto-detect now
return tryNoProxy ? ProxyUtil.autoDetectProxy(_app) : false; return tryNoProxy ? ProxyUtil.autoDetectProxy(_app) : false;
@@ -262,6 +270,33 @@ public abstract class Getdown
showContainer(); 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 * Downloads and installs (without verifying) any resources that are marked with a
* {@code PRELOAD} attribute. * {@code PRELOAD} attribute.
@@ -124,9 +124,9 @@ public final class ProxyUtil {
} }
public static boolean canLoadWithoutProxy (URL rurl, int timeoutSeconds) public static boolean canLoadWithoutProxy (URL rurl, int timeoutSeconds)
throws IOException
{ {
log.info("Attempting to fetch without proxy: " + rurl); log.info("Attempting to fetch without proxy: " + rurl);
try {
URLConnection conn = Connector.DEFAULT.open(rurl, timeoutSeconds, timeoutSeconds); 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 the appbase is not an HTTP/S URL (like file:), then we don't need a proxy
if (!(conn instanceof HttpURLConnection)) { if (!(conn instanceof HttpURLConnection)) {
@@ -142,17 +142,13 @@ public final class ProxyUtil {
if (rcode == HttpURLConnection.HTTP_PROXY_AUTH || if (rcode == HttpURLConnection.HTTP_PROXY_AUTH ||
rcode == HttpURLConnection.HTTP_FORBIDDEN) { rcode == HttpURLConnection.HTTP_FORBIDDEN) {
log.warning("Got an 'HTTP credentials needed' response", "code", rcode); log.warning("Got an 'HTTP credentials needed' response", "code", rcode);
return false;
} else { } else {
return true; return true;
} }
} finally { } finally {
hcon.disconnect(); hcon.disconnect();
} }
} catch (IOException ioe) {
log.info("Failed to HEAD " + rurl + ": " + ioe);
log.info("We probably need a proxy, but auto-detection failed.");
}
return false;
} }
public static void configProxy (Application app, String host, String port, 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.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. \ 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 \ <p> Please make sure that no virus scanner or firewall is blocking network communication with \
the server. \ the server. \