Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Monday, October 03, 2011

Tapestry: Feedback!

I often say that the three cornerstones of Tapestry are Simplicity, Consistency, Efficiency, and Feedback. Although all four of these concepts work in concert with each other, it's Feedback (keeping the developer informed when things go wrong) that is one of the most distinguishing features of Tapestry, and that's only gotten better in Tapestry 5.3.

Exception Reporting

First off, there's Tapestry's default exception report page. When an exception is thrown during a request, most often a coding error in a Tapestry page or template, Tapestry moves heaven and earth to report the exception properly. For example, in Tapestry it is not allowed for a component sub-class to define a parameter with the same name as a parameter from a base class, as this creates an ambiguity. When this situation occurs, an exception is thrown from deep in the bowels of Tapestry:

That's a start, but it's not great feedback; you'll be doing a lot of work to figure out what was going on in Tapestry leading up to the exception, and from there, figuring out how to fix it; there's lots and lots of noise in the repeated stack traces (caused by nested exceptions). However, you can see a glimmer of hope in those first few lines, the ones that start Registry [ 1], Registry [ 2], ...

Tapestry goes to a lot of trouble to track what is going on during the handling of a request; it keeps a stack of operations which describe what Tapestry is doing at any particular time. There's still a lot of internal details, but the gist of it is that Tapestry needed to create an instance of the ParameterConflictDemo page, and hit an error while doing something with the ParameterSubClass component (sorry for the ugly names, I'm using examples from Tapestry's internal test suite).

However, parsing apart the console output is NOT what a Tapestry developer does; instead they'll get all those details, and more, from the Tapestry exception report page:

Ah, much better. We're seeing the essential details from the stack of exceptions; we're seeing the associated template snippet that defines the parameter with the exception, we're seeing that operations stack neatly formatted. We see that stack of operations here as well, formatted for readability. Scrolling down, we see the stack trace of the deepest exception, formatted:

The frame in bold blue? That's a frame in the application's package, rather than code in inside Tapestry. That highlighting is very useful for letting the developer quickly figure out if the cause of the exception is a minor problem inside their code, or something more involved that shows up inside the Tapestry framework code.

Scrolling further down, we start seeing even more relevant information: all the details of the incoming request:

... well, you get the idea. Where a framework that takes feedback less seriously might give you a simple stack trace and leave the process of determining the underlying cause entirely up to you (after all, you have a debugger, right?) Tapestry fully embraces the importance of feedback: giving you all the information you need as soon as you need it (and yes, you don't have to show all that to your end users). More than that, there's attention to detail throughout Tapestry to provide real exception messages. For example, if you provide a component type name that doesn't match some component, Tapestry responds with a detailed message, including a list of all the known component types:

Again, Tapestry doesn't want you to have to put on your detective's hat to figure out what's wrong and how to fix it. It's providing all the details you need right when you need them.

Live Application Introspection

What if your problems are more subtle? How do you track down other issues, like performance problems or memory utilization? Well, Tapestry provides some introspection to address those questions as well. Tapestry 5.3 adds the Page Catalog, a special page for providing information about what pages have been loaded into memory, and a few details about how big they are, and how long they took to assemble:

Likewise, the Service Status page gives you feedback about the services defined inside the Tapestry Inversion of Control container, helping you determine what services exist, and in what state:

Deep Details

And what if you are tracking down something even more subtle? Well, by enabling some logging, Tapestry will output that operations trace as each operation starts and finishes. It's an avalance of information, much of it about instantiating services ... below is a log of just what happens when you first startup a Tapestry application, before it even processes it's first request:

Because Tapestry operates lazily, instantiating pages and services only as needed, even more happens when the first page request arrives:


In any case, the point of all this is that Tapestry provides you with the key tool, information, at all stages of development. This is central to Tapestry as a tool to be used: a framework that gets in the way, that makes any aspect of development harder or slower than it should be, is a framework that should not be used ... and I feel quite strongly that Tapestry is a framework meant to be used!

No comments: