diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java index e7248ba51..705d7a856 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java @@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleSecurityException; +import org.apache.guacamole.GuacamoleServerException; import org.apache.guacamole.GuacamoleUnauthorizedException; import org.apache.guacamole.GuacamoleSession; import org.apache.guacamole.environment.Environment; @@ -480,6 +481,18 @@ public class AuthenticationService { getLoggableAddress(request)); // Rethrow exception + e.rethrowCause(); + + // This line SHOULD be unreachable unless a bug causes + // rethrowCause() to not actually rethrow the underlying failure + Throwable cause = e.getCause(); + if (cause != null) { + logger.warn("An underlying internal error was not correctly rethrown by rethrowCause(): {}", cause.getMessage()); + logger.debug("Internal error not rethrown by rethrowCause().", cause); + } + else + logger.warn("An underlying internal error was not correctly rethrown by rethrowCause()."); + throw e.getCauseAsGuacamoleException(); } diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/GuacamoleAuthenticationProcessException.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/GuacamoleAuthenticationProcessException.java index ba1d72a50..bec73f0be 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/auth/GuacamoleAuthenticationProcessException.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/GuacamoleAuthenticationProcessException.java @@ -146,6 +146,38 @@ public class GuacamoleAuthenticationProcessException extends GuacamoleException return guacCause; } + /** + * Rethrows the original GuacamoleException wrapped within this + * GuacamoleAuthenticationProcessException. If there is no such exception, + * and the cause of this failure is an unchecked RuntimeException or Error, + * that unchecked exception/error is rethrown as-is. + * + * @throws GuacamoleException + * If the underlying cause of this exception is a checked + * GuacamoleException subclass. + * + * @throws RuntimeException + * If the underlying cause of this exception is an unchecked + * RuntimeException. + * + * @throws Error + * If the underlying cause of this exception is an unchecked Error. + */ + public void rethrowCause() throws GuacamoleException, RuntimeException, Error { + + // Rethrow any unchecked exceptions/errors as-is + Throwable cause = getCause(); + if (cause instanceof RuntimeException) + throw (RuntimeException) cause; + if (cause instanceof Error) + throw (Error) cause; + + // Pass through all other exceptions as normal GuacamoleException + // subclassses + throw getCauseAsGuacamoleException(); + + } + @Override public GuacamoleStatus getStatus() { return getCauseAsGuacamoleException().getStatus();