Hi,

I found a way to prevent the above exception from being thrown (when
T5 encounters a badly encoded URL) and return an empty EventContext to
the page's onActivate() method instead. Essentially I just advise the
ContextPathEncoder and return an empty EventContext if an
IllegalArgumentException is caught.

While this may work great for pages, can anyone see it causing
problems for other components or objects that depend on / use the
ContextPathEncoder? (For it's usage looks a little obscure to the
uninitiated.)

Full details of why I fought against the IllegalArgumentException are
given below, but beware - I think I've been working too hard or it's
gotten too late for my typing turned out to be quite, um, colloquial!

Cheers,

Steve.
----

As great as Tapestry is, the one little thing that always gets my goat
is that unannounced, nasty 500 error of:

java.lang.IllegalArgumentException:
"Input string 'Wot The?' is not valid; the character ' ' at position 4
is not valid."

You may only see it occasionally during development; you know, you're
messing with URL parameters, short cutting links and buttons when
WHAM! Error 500 in your FACE! And all you did was put a little space
between words. Nope, not allowed. That space should have been a
whopping long and ugly '$0020' instead.

I have nothing against the error. It is perfectly valid. The URL was
not properly encoded and you paid the price. But looking through the
logs of live sites I notice a lot of these "Invalid String"
exceptions. Most are produced by bad cut'n'pastes on the users'
behalf, or by text editors leaving spurious quotes on the ends of
URLs.

Being a kind and loving developer I feel a 500 Error Page is a harsh
price to pay for a bad URL - surely a 404 error or a redirect to the
home page would be far more appropriate (and would also stop my in-box
from filling up with exception reports!).

No problem, this being Tapestry, it should be easy to fix... dabble
with the onActivate() here, look at the EventContext there and nope,
nope and nope. The problem is that the exception is thrown *before*
page activation and your Page class never knew anybody cared about it.

Bad Tapestry. Surely if you're handling an EventContext and deciding
at runtime which parameters to use, the parameters can be optional
(thus you don't care if they're bad). Or Tapestry should at least give
your page the option of ignoring the parameters, throwing an exception
or returning a 404?

My methods of combating this in the past have been to check the
exception message for the words "Input string" and "is not valid" for
what Tapestry throws is not even a specific RuntimeException whose
type I can check for - but rather a generic IllegalArgumentException.
But I digress, here is a far more elegant solution:

Add the following to your Module:

@Match("ContextPathEncoder")
public static void adviseExceptionHandler(MethodAdviceReceiver
receiver) throws SecurityException, NoSuchMethodException       {
        MethodAdvice advice = new MethodAdvice() {
                public void advise(Invocation invocation) {
                        try {
                                invocation.proceed();
                        } catch (IllegalArgumentException e) {
                                String illegalPath = (String) 
invocation.getParameter(0);
                                invocation.overrideResult(new 
IllegalPathEventContext(illegalPath));
                        }
                }
        };
        Method method = ContextPathEncoder.class.getMethod("decodePath", 
String.class);
        receiver.adviseMethod(method, advice);
}

And add this simple class to your code:

import org.apache.tapestry5.EventContext;

public class IllegalPathEventContext implements EventContext {

        private String illegalPath;

        public IllegalPathEventContext(String illegalPath) {
            this.illegalPath = illegalPath;
    }

        public int getCount() {
                return 0;
        }

        public <T> T get(Class<T> desiredType, int index) {
                // should never be called because the count is always zero
                return null;
        }

    public String getIllegalPath() {
            return illegalPath;
    }
}

What this does is, whenever an illegal context path is encountered,
the annoying IllegalArgumentException is caught and empty EventContext
is returned instead.

Now when some clever clogs sticks a ' ' in your search URL or Word
leaves a hanging quote you can deal with it as if it simply wasn't
there. Or if you desire, you can check for instanceof
IllegalPathEventContext and return a 404 with the message "The illegal
path of 'I love spaces' does not exist."

Having to check for the presence of errors (in the EventContext obj)
this way is not ideal but works well if you require a robust and
client pleasing site. I'd much prefer to define a page method along
the lines of:

Object onIllegalPathInEventContext(String illegalPath);

which Tapestry calls allowing me to deal with the situation
explicitly. Maybe in a future release?

Steve.
--
Steve Eynon
mobie: (+592) 678 4236

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to