[MAGNOLIA-3566] Cache filter should ignore ClientAbortException Created: 24/Feb/11  Updated: 13/Jun/13  Resolved: 27/Mar/13

Status: Closed
Project: Magnolia
Component/s: cache
Affects Version/s: 4.3.8, 4.4.2
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Danilo Ghirardelli Assignee: Ondrej Chytil
Resolution: Not an issue Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
duplicate
is duplicated by MAGNOLIA-5112 Responses served from cache can throw... Closed
relation
is related to MGNLCACHE-48 Cache filter should rethrow exception... Closed
is related to MAGNOLIA-3595 Add an exception handler for filters. Closed
is related to MAGNOLIA-5113 Generalize/centralize treatment of br... Closed
Template:
Patch included:
Yes
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Date of First Response:

 Description   

I don't know if I'm the only one, but the cache module catches and logs this exception:

java.lang.RuntimeException: ClientAbortException: java.net.SocketException: Connection reset
at info.magnolia.module.cache.filter.CacheFilter.doFilter(CacheFilter.java:159)

It's a quite common exception, that in most cases means the browser has closed the connection. Ok, there are a few cases in which this may be useful to trace borderline problems with https and internet explorer, but I'd really like to have something to turn this off completely instead of having something harmless cluttering log file at error level...
Disabling the log completely for the cacheFilter class is not a good idea, and using the log4j extras to filter out a single exception isn't a good solution either.
The exception re-thrown from this filter is wrapped in a runtime exception, so it's not even immediate to catch and ignore those exceptions in another filter in the chain.



 Comments   
Comment by Danilo Ghirardelli [ 10/Mar/11 ]

ClientAbortException is a Tomcat-specific exception, but I suppose each application server has its own for the same reason. I solved my problem replacing the cacheFilter class with a simple class that extends the original cacheFilter and does just this:

    public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
        throws IOException, ServletException {
        try {
            super.doFilter(request, response, chain);
        } catch (RuntimeException e) {
            Throwable wrappedEx = ExceptionUtils.getCause(e);
            if (!((wrappedEx != null) && (StringUtils.equalsIgnoreCase(wrappedEx.getClass().getName(),
                "org.apache.catalina.connector.ClientAbortException")))) {
                // Propagate ONLY if it's not a client abort.
                throw e;
            } // Otherwise just ignore it.
        }
    }

Comment by Danilo Ghirardelli [ 10/Mar/11 ]

I started thinking that in the filter chain there are a few point where a pluggable exception handler may be really useful. This and also rendering filter, just to name two. It may be just a class stated in the configuration node, maybe it's worth even defining the exception handler on the abstract filter and overriding it where needed.
If you are interested in the idea I may open a new issue for that.

Comment by Philipp Bärfuss [ 11/Mar/11 ]

Thanks, especially for the code snipped.

Comment by Ondrej Chytil [ 27/Mar/13 ]

Cannot reproduce the issue with current 4.4 and 4.5 snapshots.

Comment by Danilo Ghirardelli [ 27/Mar/13 ]

Locally is almost impossible, you need real load to reproduce this.
To reproduce the issue locally, you should do something like this:

  • start the application locally with java debugging enabled.
  • put a breakpoint in the cache filter, just at the beginning of the doFilter.
  • do a request from the browser and wait until it reaches the breakpoint.
  • do not move from breakpoint, leave the execution stopped there
  • close the browser (do not just close the tab, in some browser it might not be enough)
  • resume execution

The "problem" happens when a user closes it browser while the the server is streaming the response. In a local machine this is istantaneous, you need to simulate a little delay to have the time to stop the request. The "exception" generated is nothing bad, because the user already left, the point is just avoiding this in the log.

And it is still perfectly reproducible on 4.4 (didn't try on 4.5).

Comment by Ondrej Chytil [ 27/Mar/13 ]

Hi Danilo,

my test case was big file in DMS workspace accessed from command line (curl), stopped in the middle of the request. While on 4.4.2 I got the exception, on 4.4.11-SNAPSHOT and 4.5.9-SNAPSHOT I was unable to do so.
Anyway I never managed to reproduce it just by closing the browser (even when stream was not finished).

And it is still perfectly reproducible on 4.4 (didn't try on 4.5).

Which version did you use?

Comment by Danilo Ghirardelli [ 29/Mar/13 ]

Magnolia 4.4.8 on Tomcat 6.0.24 (which is not the last version), locally on a windows system (and in production on a linux system). Maybe the problem is more linked to Tomcat version/installation than to the filter itself.

Anyway, more than the single patch for Tomcat (or other application servers), my real issue was about having a way to handle exceptions in the filter chain to fix cases like this...

Comment by Magnolia International [ 13/Jun/13 ]

ochytil the issue still exists. The reason you didn't see it with a large file is because those go a different route (with DelegatingBlobCachedEntry) and never get cached. If you do it with a resource that's cached, thus served with UseCache, you'll see the fix. Fixed it in 4.5.x and 5.0 with MAGNOLIA-5112. Danilo's proposal might serve as a basis for an improved solution later on.

Generated at Mon Feb 12 03:47:41 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.