News: How line precise error reporting is implemented

  1. Tapestry users always rave about the level of error reporting that they get. Howard Lewis-Ship takes this very seriously, and implements "line precise error reporting" in his projects. He has been asked how he does this, and explains it in his recent entry.
    Line precise error reporting isn't the end all of Feedback. Malcolm Edgar, a one-time Tapestry committer, has been working on his own web framework (I believe for internal use at his company) ... it goes one step further, actually displaying the content of his equivalent to an HTML template and highlighting the line that's in error. That's raising the bar, but perhaps Tapestry will catch up to that some day.

    Further, simply reporting locations isn't enough. If I pass a null value into a method that doesn't allow null, I want to see a detailed exception (You must supply a non-null value for parameter 'action'.) rather than a NullPointerException. A detailed exception gives me, the developer, a head start on actually fixing the problem. Explicit checking along these lines means that the location that's actually reported will be more accurate as well, especially considering that there's no way to attach a location to a NullPointerException.
    Read more in: By Request: How Line Precise Error Reporting is implemented

    Threaded Messages (10)

  2. Error at Message 122427, line 1, column 85: Blogger "Lewis-Ship" not found.

    So, who'se this "Lewis-Ship" person, anyway? My last name is "Lewis Ship".

    Howard M. Lewis Ship
    Independent J2EE / Open-Source Java Consultant
    Creator, Jakarta Tapestry
    Creator, Jakarta HiveMind
  3. Error at Message 122427, line 1, column 85: Blogger "Lewis-Ship" not found.So, who'se this "Lewis-Ship" person, anyway? My last name is "Lewis Ship".--Howard M. Lewis ShipIndependent J2EE / Open-Source Java ConsultantCreator, Jakarta TapestryCreator, Jakarta HiveMindhttp://howardlewisship.com
    Error at Message 122438, line 3, column 5: Word "who'se" not found.
    Error at Message 122438, line 3, column 55: Blogger "Howard Lewis Ship" not found.

    I think it should be "who's" and "Howard M. Lewis Ship" :-)
  4. "who's" is the contraction of "who is". "whose" is the possessive. "who'se" isn't a word.


    HTH, HAND.
  5. Oops[ Go to top ]

    I'm an idiot.
  6. Oops[ Go to top ]

    Yeah, its nice to have "precise" error messages, but honestly... is it that big of a deal? I mean, if I get an NPE (and the concomitant stack trace) don't I have enough info to fix the problem within a reasonable amount of time? When is the last time you got an NPE that caused you to burn hours trying to find? Are the man-hours that will be/were spent on adding this feature to a framework worth it? If an NPE occurs on a system in production, do I need this feature to point the user to the exact line that contained the bug that slipped through the cracks of my unit tests /integration tests/ code reviews / QA processes, etc? Or, should I just kick them to the main page, log the error, potentially send an email/page/text message to the admin and pretend like nothing happened? I dunno.
  7. Oops[ Go to top ]

    This stuff is very handy for frameworks which make heavy use of XML, ie. just about everyting in the J2EE space. A lot of the framework designs are moving code out into XML configuration files, so it becomes important for the framework to help you debug XML configuration errors and HTML template errors.
  8. Way off topic. XML rant.[ Go to top ]

    I hate the way that folks climb on XML simply because its fun, then find they need way more validation that ever before because xml is easy to mess up (even validated/verified).

    How often you you seen, or indeed proposed, writing some form of XML macro language? The proposal is usually something like 'Java is fixed at compile time, which is bad, so we shall decouple the system for runtime config using XML. What's even better is I have an idea for an XML macro system which means we can :implement logic, get rid of the database, switch app servers, embed sql, etc.'

    This creates heaps of runtime errors, creates a maintenance nightmare, and usually gets scrapped after 3 to 18 months because no one else thinks its a good idea. Even the maintenance boys hate them.

    Java is fixed at compile time, which is GOOD. The compiler is a vital tool in producing code that works.

  9. I mean, if I get an NPE (and the concomitant stack trace) don't I have enough info to fix the problem within a reasonable amount of time?
    These kind of statements can never been "proven" in the theoretical, so let's switch over to the practical.

    You would suspect that I, being the author of Tapestry, would find it quite easy to work back from a stack trace of some NPE or other exception and jump immediately to the error. You would be wrong.

    Tapestry is a framework, meaning a lot of the code is inside the framework (that's the whole point). And Tapestry's render process is quite recursive. That means that a typical stack trace is a whole bunch of BaseComponent.renderComponent() calls. Stack traces don't identify the object, just the class ... so there's not a lot of useful information there per se.

    So paying attention to exception messages (avoiding NPEs, adding checks and producing more descriptive error messages) was a good start. Getting that information out to the user (often hidden inside a layer or two of wrapping exceptions) was also key.

    However, in Tapestry (and HiveMind, and any decent framework) objects collaborate. So a misconfiguration of object A that gets passed through object B to object C may fail inside object C. Is that a problem in object C? No! That's a failure of object A. B and C are innocent bystanders. The exception thrown by C will present the location of A!

    When I put in the effort (over a year ago) to add this to Tapestry, I was dubious about its effort. As I said, I'm the Tapestry master, how much time could it save me? As with many things, I was wrong ... my personal productivity skyrocketed as soon as I put this in place, since every typo or other error produced a report showing me the precise line to fix. No hunting, no guessing, no global search.
  10. I've had to maintain code that has lines invoking several chained calls or operating on several variables together that throws a NullPointerException. Now, I've never used Tapestry, so forgive me if my past experiences don't apply here.

    Without a descriptive error in the case I described above, I've been forced to (a) search back through the stack to find out where each of the variables came from and which could be null and then (b) reproduce it locally attempting to set each variable to null. If instead I have descriptive error messages tellign me which variable was null (i.e. a pre-condition check), then part (a) is eliminated and part (b) is reduced to reproducing only one scenario instead of multiple.

    That said, you should just kick the user to the main page with a general message, but log the *detail* of the problem and alert an administrator via email/page/test message and let your application continue. Proper error handling should be able to stop the system from propogating a bad state and simply abort the action that would've caused the bad state.
  11. I agree with Howard -- as a primary contributor to the WebWork framework I can say without a doubt that there are times I wish we had better error reporting. Needless to say, 90% of the errors we get aren't because of WebWork but rather because a Velocity template isn't building correctly and its reporting is horrible.

    I recently played with FreeMarker and it was a a breath of fresh air when it came to error reporting.

    In short: precise reporting is very important, and even more important in frameworks where the consumer _is_ the developer.