Hi Andrea and Justin,
that´s a good thing that there´s already a way to handle this. Thanks for pointing out.
Still wondering though, if all and every exception should be ignored.
The maxRenderingErrors setting docs say "...Usually GetMap skips over faulty features, reprojection errors and the like in an attempt to serve the results anyways. This makes for a best effort rendering...", like it is intended to tolerate some "rendering" errors (faulty features, reprojection errors) which is good. But what about actual IO errors (ie, the source data can't be read at all).
In the end I keep on thinking that a request that cannot be fulfilled by the underlying data source shouldn't give a false positive GetMap wise.
By looking at it I realize how difficult it would be given the state of affair with the api contracts and actual implementations, and this may open some sort of "exception handling best practices" vs "pragmatism and adaptation to what we have and we don't have the resources to improve" debate.
So far so good. It's not my intention to get involved in that kind of high heat debate, but I would like to hear your opinions anyway.
As a first apprach, and sticking to what we do have right now instead of ranting about usage of checked vs unchecked exceptions, I would say:
During a rendering phase, these are the most probable exceptions that could be caught:
1- IOException: from FeatureReader.hasNext(), FeatureReader.next(), FeatureSource.getFeatures/getBounds/getCount, GridCoverageReader.read(). All the declared places in the API indicate it should be thrown if there are errors fulfilling the request. Quite vague, and hence we all ended up throwing IOException everywhere whether the user is expected to take some recovery/cleanup action after it or not.
2- IllegalAttributeException: unchecked, a data error.
3- NoSuchElementException: calling next() when hasNext() == false. A programming error, hence unchecked. Cool.
4- IllegalArgumentException: contract precondition violations. Hence unchecked, non declared. Cool.
From the above, it seems to me like an IOException should stop the rendered and GetMap should fail. The nasty thing is that TransformException, FactoryException, etc are usually wrapped to an IOException instead of to a RuntimeException, which IMHO should be the way to go. And that's the reason why GetMap eats IOExceptions too. Now Andrea stop me if I'm wrong, it's getting large already 
So in the end by eating them all we're not taking control of what makes sense for the renderer to keep going, but instead are potentially hiding programming errors and returning "false positive" responses.
My proposal is then that given an exception event thrown by the renderer, the GetMap operation walks down the exception cause hierarchy and keeps going only if the cause is one that we actually want to ignore (IllegalAttributeException/TransformationException/any one else?).
Looking forward to your insights.
Cheers,
Gabriel
PS: the javadoc for FeatureReader.next() and it's declaration is inconsistent, we should fix this (note it is documented to throw IllegalAttributeException whilst it declares to throw IllegalArgumentException instead):
/**
* Reads the next Feature in the FeatureReader.
* @return The next feature in the reader.
* @throws IOException If an error occurs reading the
* @throws IllegalAttributeException If the attributes read do not
* with the
* @throws NoSuchElementException If there are no more Features in
* Reader.
*/
F next() throws IOException, IllegalArgumentException, NoSuchElementException;
Andrea Aime wrote:
Justin Deoliveira ha scritto:
Tough problem. I think behavior depending on the type of exception would be hard to pull off simply because the types of exceptions thrown by datastores, etc.. are sort of all over the place. There has never really been clear guidelines as to what exceptions to throw in what cases.
What about simply a configuration option or a format option that controls this behavior? Something like "format_options=lenient:false" would case the render to halt rendering when an exception occurs? Not sure if that works or not, but it would be my first idea.
The code is sort of already there, but it's not a per request setting.
If you look into DefaultRasterMapProducer it attaches a MaxErrorEnforcer
to the renderer, which in the end is a listener.
If the max error count is set to 1, the rendering will stop after the
first error and the error will be returned in the service exception.
The enforcer has been introduced as part of the "wms limits" work
and can be configured as documented here:
http://docs.geoserver.org/1.7.x/user/services/wms/configuration.html#request-limits
I guess that, if needed, we could add format_options configs
that allows further restricting the server default limits (but not
enlarging, that would go against the very purpose of setting up
the limits, that is, allow the admin to assert control over the
stability of his server).
Cheers
Andrea
--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.