Do not show stack trace for client-side connection errors

The `ClientAbortException` exception indicates that the connection was
closed by the client, usually for something the server can do nothing
about (e.g. navigating outside of the page while it's loading).

Since this error happens often, this commit displays shorter error
messages when it does, without a large stack trace.

All other exceptions are handled just as before.
master
François-Xavier Thomas 6 years ago
parent f04ec61d0f
commit 417583ccaa
  1. 5
      airsonic-main/src/main/java/org/airsonic/player/controller/StreamController.java
  2. 11
      airsonic-main/src/main/java/org/airsonic/player/spring/LoggingExceptionResolver.java
  3. 15
      airsonic-main/src/main/java/org/airsonic/player/util/Util.java

@ -249,8 +249,8 @@ public class StreamController {
} }
} }
} }
} catch (ClientAbortException err) { } catch (ClientAbortException e) {
LOG.info("org.apache.catalina.connector.ClientAbortException: Connection reset"); LOG.info("{}: Client unexpectedly closed connection while loading {} ({})", request.getRemoteAddr(), Util.getURLForRequest(request), e.getCause().toString());
return; return;
} finally { } finally {
if (status != null) { if (status != null) {
@ -426,5 +426,4 @@ public class StreamController {
out.write(buf); out.write(buf);
out.flush(); out.flush();
} }
} }

@ -1,5 +1,6 @@
package org.airsonic.player.spring; package org.airsonic.player.spring;
import org.airsonic.player.util.Util;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
@ -11,13 +12,17 @@ import javax.servlet.http.HttpServletResponse;
public class LoggingExceptionResolver implements HandlerExceptionResolver, Ordered { public class LoggingExceptionResolver implements HandlerExceptionResolver, Ordered {
private static final Logger logger = LoggerFactory.getLogger(LoggingExceptionResolver.class); private static final Logger LOG = LoggerFactory.getLogger(LoggingExceptionResolver.class);
@Override @Override
public ModelAndView resolveException( public ModelAndView resolveException(
HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e HttpServletRequest request, HttpServletResponse response, Object o, Exception e
) { ) {
logger.error("Exception occurred", e); if (e instanceof org.apache.catalina.connector.ClientAbortException) {
LOG.info("{}: Client unexpectedly closed connection while loading {} ({})", request.getRemoteAddr(), Util.getURLForRequest(request), e.getCause().toString());
} else {
LOG.error("{}: An exception occurred while loading {}", request.getRemoteAddr(), Util.getURLForRequest(request), e);
}
return null; return null;
} }

@ -25,6 +25,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
@ -117,4 +118,18 @@ public final class Util {
return ""; return "";
} }
} }
/**
* Return a complete URL for the given HTTP request,
* including the query string.
*
* @param request An HTTP request instance
* @return The associated URL
*/
public static String getURLForRequest(HttpServletRequest request) {
String url = request.getRequestURL().toString();
String queryString = request.getQueryString();
if (queryString != null && queryString.length() > 0) url += "?" + queryString;
return url;
}
} }

Loading…
Cancel
Save