Make it work even if Tomcat-specific exceptions are not available

When Tomcat is not available (for example, when using Jetty), the
ClientAbortException is not available either, causing an error when
starting the server.

This commit fixes that, and instead catches that exception (or its Jetty
equivalent) via reflection.
master
François-Xavier Thomas 6 years ago
parent ec96b9711d
commit 51b738053f
  1. 20
      airsonic-main/src/main/java/org/airsonic/player/controller/StreamController.java
  2. 14
      airsonic-main/src/main/java/org/airsonic/player/spring/LoggingExceptionResolver.java
  3. 12
      airsonic-main/src/main/java/org/airsonic/player/util/Util.java

@ -29,7 +29,6 @@ import org.airsonic.player.service.sonos.SonosHelper;
import org.airsonic.player.util.HttpRange; import org.airsonic.player.util.HttpRange;
import org.airsonic.player.util.StringUtil; import org.airsonic.player.util.StringUtil;
import org.airsonic.player.util.Util; import org.airsonic.player.util.Util;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -249,9 +248,22 @@ public class StreamController {
} }
} }
} }
} catch (ClientAbortException e) { } catch (IOException e) {
LOG.info("{}: Client unexpectedly closed connection while loading {} ({})", request.getRemoteAddr(), Util.getURLForRequest(request), e.getCause().toString());
return; // This happens often and outside of the control of the server, so
// we catch Tomcat/Jetty "connection aborted by client" exceptions
// and display a short error message.
boolean shouldCatch = false;
shouldCatch |= Util.isInstanceOfClassName(e, "org.apache.catalina.connector.ClientAbortException");
shouldCatch |= Util.isInstanceOfClassName(e, "org.eclipse.jetty.io.EofException");
if (shouldCatch) {
LOG.info("{}: Client unexpectedly closed connection while loading {} ({})", request.getRemoteAddr(), Util.getURLForRequest(request), e.getCause().toString());
return;
}
// Rethrow the exception in all other cases
throw e;
} finally { } finally {
if (status != null) { if (status != null) {
securityService.updateUserByteCounts(user, status.getBytesTransfered(), 0L, 0L); securityService.updateUserByteCounts(user, status.getBytesTransfered(), 0L, 0L);

@ -18,11 +18,19 @@ public class LoggingExceptionResolver implements HandlerExceptionResolver, Order
public ModelAndView resolveException( public ModelAndView resolveException(
HttpServletRequest request, HttpServletResponse response, Object o, Exception e HttpServletRequest request, HttpServletResponse response, Object o, Exception e
) { ) {
if (e instanceof org.apache.catalina.connector.ClientAbortException) { // This happens often and outside of the control of the server, so
// we catch Tomcat/Jetty "connection aborted by client" exceptions
// and display a short error message.
boolean shouldCatch = false;
shouldCatch |= Util.isInstanceOfClassName(e, "org.apache.catalina.connector.ClientAbortException");
shouldCatch |= Util.isInstanceOfClassName(e, "org.eclipse.jetty.io.EofException");
if (shouldCatch) {
LOG.info("{}: Client unexpectedly closed connection while loading {} ({})", request.getRemoteAddr(), Util.getURLForRequest(request), e.getCause().toString()); LOG.info("{}: Client unexpectedly closed connection while loading {} ({})", request.getRemoteAddr(), Util.getURLForRequest(request), e.getCause().toString());
} else { return null;
LOG.error("{}: An exception occurred while loading {}", request.getRemoteAddr(), Util.getURLForRequest(request), e);
} }
// Display a full stack trace in all other cases
LOG.error("{}: An exception occurred while loading {}", request.getRemoteAddr(), Util.getURLForRequest(request), e);
return null; return null;
} }

@ -132,4 +132,16 @@ public final class Util {
if (queryString != null && queryString.length() > 0) url += "?" + queryString; if (queryString != null && queryString.length() > 0) url += "?" + queryString;
return url; return url;
} }
/**
* Return true if the given object is an instance of the class name in argument.
* If the class doesn't exist, returns false.
*/
public static boolean isInstanceOfClassName(Object o, String className) {
try {
return Class.forName(className).isInstance(o);
} catch (ClassNotFoundException e) {
return false;
}
}
} }

Loading…
Cancel
Save